summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
commit0292059f4a16434600564cfa3f0ad2309a508a54 (patch)
treed95953cd53011917c4df679b96aedca39401b54f
downloadlibksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.tar.gz
libksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.zip
Added libksquirrel for KDE3
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/libraries/libksquirrel@1095624 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r--AUTHORS1
-rw-r--r--COPYING58
-rw-r--r--ChangeLog555
-rw-r--r--INSTALL22
-rw-r--r--LICENSE481
-rw-r--r--LICENSE.GPL340
-rw-r--r--LICENSE.JASPER50
-rw-r--r--LICENSE.LJPEG79
-rw-r--r--LICENSE.MNG56
-rw-r--r--LICENSE.PNG109
-rw-r--r--Makefile.am24
-rw-r--r--Makefile.dist14
-rw-r--r--README41
-rw-r--r--VERSION1
-rw-r--r--acinclude.m411864
-rw-r--r--aclocal.m43073
-rwxr-xr-xbuilddeb14
-rwxr-xr-xconfig.guess1561
-rw-r--r--config.log355
-rwxr-xr-xconfig.sub1686
-rw-r--r--configure.ac869
-rwxr-xr-xconfigure.gnu8
-rw-r--r--description-pak1
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/html/Makefile.am22
-rw-r--r--doc/html/belka_bkgr.gifbin0 -> 18507 bytes
-rw-r--r--doc/html/bits.html44
-rw-r--r--doc/html/development-highlev.html82
-rw-r--r--doc/html/how_to_build_arrow.pngbin0 -> 4023 bytes
-rw-r--r--doc/html/how_to_build_c++.pngbin0 -> 13939 bytes
-rw-r--r--doc/html/how_to_build_c.pngbin0 -> 13747 bytes
-rw-r--r--doc/html/how_to_build_codec.pngbin0 -> 12672 bytes
-rw-r--r--doc/html/index.html26
-rw-r--r--doc/html/ksquirrel-libs-about.html24
-rw-r--r--doc/html/ksquirrel-libs-fio.html140
-rw-r--r--doc/html/ksquirrel-libs-metainfo.html55
-rw-r--r--doc/html/ksquirrel-libs-olibs.html28
-rw-r--r--doc/html/ksquirrel-libs-olibs1.html129
-rw-r--r--doc/html/ksquirrel-libs-olibs2.html1620
-rw-r--r--doc/html/ksquirrel-libs-olibs3.html365
-rw-r--r--doc/html/ksquirrel-libs-struct.html201
-rw-r--r--doc/html/styles.css26
-rw-r--r--doc/sources/Makefile.am24
-rw-r--r--doc/sources/c++/README3
-rwxr-xr-xdoc/sources/c++/compile5
-rw-r--r--doc/sources/c++/main.cpp44
-rw-r--r--doc/sources/c++/polygon.hpp25
-rw-r--r--doc/sources/c++/triangle.cpp22
-rwxr-xr-xdoc/sources/c/compile5
-rw-r--r--doc/sources/c/main.c56
-rw-r--r--doc/sources/c/module.c4
-rw-r--r--doc/sources/ttx/Makefile.am9
-rw-r--r--doc/sources/ttx/README3
-rwxr-xr-xdoc/sources/ttx/compile-c++8
-rw-r--r--doc/sources/ttx/fmt_codec_ttx.cpp116
-rw-r--r--doc/sources/ttx/fmt_codec_ttx.h37
-rw-r--r--doc/sources/ttx/fmt_codec_ttx_defs.h27
-rw-r--r--examples/qtapp/main.cpp24
-rw-r--r--examples/qtapp/myqt.cpp111
-rw-r--r--examples/qtapp/myqt.h33
-rw-r--r--examples/qtapp/qtapp.pro11
-rw-r--r--examples/qtgl/main.cpp30
-rw-r--r--examples/qtgl/myqgl.cpp182
-rw-r--r--examples/qtgl/myqgl.h40
-rw-r--r--examples/qtgl/qtgl.pro12
-rw-r--r--examples/w3.bmpbin0 -> 49202 bytes
-rw-r--r--kernel/Makefile.am123
-rwxr-xr-xkernel/generate223
-rw-r--r--kernel/include/fmt_codec_avs.h39
-rw-r--r--kernel/include/fmt_codec_bmp.h46
-rw-r--r--kernel/include/fmt_codec_cd_func.h35
-rw-r--r--kernel/include/fmt_codec_cut.h38
-rw-r--r--kernel/include/fmt_codec_dds.h39
-rw-r--r--kernel/include/fmt_codec_fli.h42
-rw-r--r--kernel/include/fmt_codec_gif.h45
-rw-r--r--kernel/include/fmt_codec_hdr.h42
-rw-r--r--kernel/include/fmt_codec_ico.h43
-rw-r--r--kernel/include/fmt_codec_iff.h41
-rw-r--r--kernel/include/fmt_codec_jbig.h34
-rw-r--r--kernel/include/fmt_codec_jpeg.h48
-rw-r--r--kernel/include/fmt_codec_jpeg2000.h51
-rw-r--r--kernel/include/fmt_codec_koala.h39
-rw-r--r--kernel/include/fmt_codec_lif.h39
-rw-r--r--kernel/include/fmt_codec_mac.h37
-rw-r--r--kernel/include/fmt_codec_mdl.h40
-rw-r--r--kernel/include/fmt_codec_mng.h51
-rw-r--r--kernel/include/fmt_codec_msp.h41
-rw-r--r--kernel/include/fmt_codec_mtv.h39
-rw-r--r--kernel/include/fmt_codec_openexr.h45
-rw-r--r--kernel/include/fmt_codec_pcx.h40
-rw-r--r--kernel/include/fmt_codec_pix.h34
-rw-r--r--kernel/include/fmt_codec_png.h63
-rw-r--r--kernel/include/fmt_codec_pnm.h48
-rw-r--r--kernel/include/fmt_codec_psd.h41
-rw-r--r--kernel/include/fmt_codec_psp.h53
-rw-r--r--kernel/include/fmt_codec_pxr.h34
-rw-r--r--kernel/include/fmt_codec_ras.h43
-rw-r--r--kernel/include/fmt_codec_rawrgb.h40
-rw-r--r--kernel/include/fmt_codec_sct.h37
-rw-r--r--kernel/include/fmt_codec_sgi.h40
-rw-r--r--kernel/include/fmt_codec_sun.h38
-rw-r--r--kernel/include/fmt_codec_tga.h40
-rw-r--r--kernel/include/fmt_codec_tiff.h46
-rw-r--r--kernel/include/fmt_codec_ttf.h34
-rw-r--r--kernel/include/fmt_codec_utah.h38
-rw-r--r--kernel/include/fmt_codec_wal.h39
-rw-r--r--kernel/include/fmt_codec_wbmp.h49
-rw-r--r--kernel/include/fmt_codec_wmf.h39
-rw-r--r--kernel/include/fmt_codec_xbm.h40
-rw-r--r--kernel/include/fmt_codec_xcur.h43
-rw-r--r--kernel/include/fmt_codec_xpm.h44
-rw-r--r--kernel/include/fmt_codec_xwd.h38
-rw-r--r--kernel/include/ksquirrel-libs/error.h49
-rw-r--r--kernel/include/ksquirrel-libs/fileio.h73
-rw-r--r--kernel/include/ksquirrel-libs/fmt_codec_base.h258
-rw-r--r--kernel/include/ksquirrel-libs/fmt_defs.h242
-rw-r--r--kernel/include/ksquirrel-libs/fmt_types.h36
-rw-r--r--kernel/include/ksquirrel-libs/fmt_utils.h64
-rw-r--r--kernel/include/ksquirrel-libs/settings.h69
-rw-r--r--kernel/kls_avs/Makefile.am9
-rw-r--r--kernel/kls_avs/fmt_codec_avs.cpp207
-rw-r--r--kernel/kls_avs/fmt_codec_avs_defs.h27
-rw-r--r--kernel/kls_bmp/Makefile.am9
-rw-r--r--kernel/kls_bmp/fmt_codec_bmp.cpp445
-rw-r--r--kernel/kls_bmp/fmt_codec_bmp_defs.h58
-rw-r--r--kernel/kls_camera/Makefile.am39
-rw-r--r--kernel/kls_camera/dcraw.c8269
-rw-r--r--kernel/kls_camera/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_camera/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_camera/ksquirrel-libs-camera2ppm.in20
-rw-r--r--kernel/kls_camera/libkls_camera.so.ui1023
-rw-r--r--kernel/kls_cut/Makefile.am9
-rw-r--r--kernel/kls_cut/fmt_codec_cut.cpp173
-rw-r--r--kernel/kls_cut/fmt_codec_cut_defs.h25
-rw-r--r--kernel/kls_dds/Makefile.am9
-rw-r--r--kernel/kls_dds/dds.cpp1066
-rw-r--r--kernel/kls_dds/dds.h36
-rw-r--r--kernel/kls_dds/fmt_codec_dds.cpp143
-rw-r--r--kernel/kls_dds/fmt_codec_dds_defs.h27
-rw-r--r--kernel/kls_dicom/Makefile.am15
-rw-r--r--kernel/kls_dicom/fmt_codec_png.cpp655
-rw-r--r--kernel/kls_dicom/fmt_codec_png_defs.h27
-rw-r--r--kernel/kls_dicom/ksquirrel-libs-dicom2png.in3
-rw-r--r--kernel/kls_djvu/Makefile.am17
-rw-r--r--kernel/kls_djvu/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_djvu/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_djvu/libkls_djvu.so.ui195
-rw-r--r--kernel/kls_dxf/Makefile.am17
-rw-r--r--kernel/kls_dxf/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_dxf/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_dxf/libkls_dxf.so.ui192
-rw-r--r--kernel/kls_eps/Makefile.am11
-rw-r--r--kernel/kls_eps/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_eps/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_fig/Makefile.am15
-rw-r--r--kernel/kls_fig/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_fig/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_fig/ksquirrel-libs-fig2ppm.in3
-rw-r--r--kernel/kls_fli/Makefile.am9
-rw-r--r--kernel/kls_fli/fmt_codec_fli.cpp449
-rw-r--r--kernel/kls_fli/fmt_codec_fli_defs.h92
-rw-r--r--kernel/kls_gif/Makefile.am9
-rw-r--r--kernel/kls_gif/fmt_codec_gif.cpp516
-rw-r--r--kernel/kls_gif/fmt_codec_gif_defs.h32
-rw-r--r--kernel/kls_hdr/Makefile.am9
-rw-r--r--kernel/kls_hdr/fmt_codec_hdr.cpp332
-rw-r--r--kernel/kls_hdr/fmt_codec_hdr_defs.h32
-rw-r--r--kernel/kls_ico/Makefile.am9
-rw-r--r--kernel/kls_ico/fmt_codec_ico.cpp296
-rw-r--r--kernel/kls_ico/fmt_codec_ico_defs.h63
-rw-r--r--kernel/kls_iff/Makefile.am15
-rw-r--r--kernel/kls_iff/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_iff/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_iff/ksquirrel-libs-iff2ppm.in3
-rw-r--r--kernel/kls_jbig/Makefile.am11
-rw-r--r--kernel/kls_jbig/fmt_codec_jbig.cpp148
-rw-r--r--kernel/kls_jbig/fmt_codec_jbig_defs.h27
-rw-r--r--kernel/kls_jbig/jbig2mem.cpp270
-rw-r--r--kernel/kls_jbig/jbig2mem.h6
-rw-r--r--kernel/kls_jbig/libjbig/ANNOUNCE147
-rw-r--r--kernel/kls_jbig/libjbig/COPYING339
-rw-r--r--kernel/kls_jbig/libjbig/Makefile.am5
-rw-r--r--kernel/kls_jbig/libjbig/jbig.c3190
-rw-r--r--kernel/kls_jbig/libjbig/jbig.h270
-rw-r--r--kernel/kls_jbig/libjbig/jbig_tab.c428
-rw-r--r--kernel/kls_jpeg/Makefile.am9
-rw-r--r--kernel/kls_jpeg/fmt_codec_jpeg.cpp308
-rw-r--r--kernel/kls_jpeg/fmt_codec_jpeg_defs.h42
-rw-r--r--kernel/kls_jpeg2000/Makefile.am9
-rw-r--r--kernel/kls_jpeg2000/fmt_codec_jpeg2000.cpp277
-rw-r--r--kernel/kls_jpeg2000/fmt_codec_jpeg2000_defs.h28
-rw-r--r--kernel/kls_koala/Makefile.am9
-rw-r--r--kernel/kls_koala/fmt_codec_koala.cpp207
-rw-r--r--kernel/kls_koala/fmt_codec_koala_defs.h39
-rw-r--r--kernel/kls_leaf/Makefile.am15
-rw-r--r--kernel/kls_leaf/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_leaf/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_leaf/ksquirrel-libs-leaf2ppm.in3
-rw-r--r--kernel/kls_lif/Makefile.am9
-rw-r--r--kernel/kls_lif/fmt_codec_lif.cpp155
-rw-r--r--kernel/kls_lif/fmt_codec_lif_defs.h41
-rw-r--r--kernel/kls_ljpeg/Makefile.am17
-rw-r--r--kernel/kls_ljpeg/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_ljpeg/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in18
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/Copyright79
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/Makefile.am5
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/huffd.c665
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/io.h105
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/jpeg.h249
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c263
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/mcu.c125
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/mcu.h63
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/predictor.c189
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/predictor.h176
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/proto.h75
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/read.c665
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/util.c297
-rw-r--r--kernel/kls_mac/Makefile.am15
-rw-r--r--kernel/kls_mac/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_mac/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_mac/ksquirrel-libs-mac2ppm.in3
-rw-r--r--kernel/kls_mdl/Makefile.am9
-rw-r--r--kernel/kls_mdl/fmt_codec_mdl.cpp171
-rw-r--r--kernel/kls_mdl/fmt_codec_mdl_defs.h35
-rw-r--r--kernel/kls_mng/Makefile.am9
-rw-r--r--kernel/kls_mng/fmt_codec_mng.cpp372
-rw-r--r--kernel/kls_mng/fmt_codec_mng_defs.h27
-rw-r--r--kernel/kls_msp/Makefile.am9
-rw-r--r--kernel/kls_msp/fmt_codec_msp.cpp228
-rw-r--r--kernel/kls_msp/fmt_codec_msp_defs.h49
-rw-r--r--kernel/kls_mtv/Makefile.am9
-rw-r--r--kernel/kls_mtv/fmt_codec_mtv.cpp196
-rw-r--r--kernel/kls_mtv/fmt_codec_mtv_defs.h27
-rw-r--r--kernel/kls_neo/Makefile.am15
-rw-r--r--kernel/kls_neo/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_neo/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_neo/ksquirrel-libs-neo2ppm.in3
-rw-r--r--kernel/kls_openexr/Makefile.am11
-rw-r--r--kernel/kls_openexr/fmt_codec_openexr.cpp303
-rw-r--r--kernel/kls_openexr/fmt_codec_openexr_defs.h27
-rw-r--r--kernel/kls_pcx/Makefile.am9
-rw-r--r--kernel/kls_pcx/fmt_codec_pcx.cpp256
-rw-r--r--kernel/kls_pcx/fmt_codec_pcx_defs.h48
-rw-r--r--kernel/kls_pi1/Makefile.am15
-rw-r--r--kernel/kls_pi1/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_pi1/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_pi1/ksquirrel-libs-pi12ppm.in3
-rw-r--r--kernel/kls_pi3/Makefile.am15
-rw-r--r--kernel/kls_pi3/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_pi3/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_pi3/ksquirrel-libs-pi32ppm.in3
-rw-r--r--kernel/kls_pict/Makefile.am15
-rw-r--r--kernel/kls_pict/fmt_codec_pnm.cpp1469
-rw-r--r--kernel/kls_pict/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_pict/ksquirrel-libs-pict2ppm.in3
-rw-r--r--kernel/kls_pix/Makefile.am9
-rw-r--r--kernel/kls_pix/fmt_codec_pix.cpp156
-rw-r--r--kernel/kls_pix/fmt_codec_pix_defs.h36
-rw-r--r--kernel/kls_png/Makefile.am15
-rw-r--r--kernel/kls_png/README2
-rw-r--r--kernel/kls_png/fmt_codec_png.cpp655
-rw-r--r--kernel/kls_png/fmt_codec_png_defs.h27
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/Makefile.am8
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/png.c792
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/png.h3672
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngconf.h1490
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngerror.c341
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pnggccrd.c101
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngget.c1062
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pnghack.h409
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngmem.c608
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngpread.c1773
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngread.c1604
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngrio.c167
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngrtran.c4284
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngrutil.c3392
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngset.c1383
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngtest.c1551
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngtrans.c662
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngvcrd.c1
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngwio.c234
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngwrite.c1549
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngwtran.c572
-rw-r--r--kernel/kls_png/ksquirrel-libs-png/pngwutil.c2920
-rw-r--r--kernel/kls_pnm/Makefile.am11
-rw-r--r--kernel/kls_pnm/fmt_codec_pnm.cpp1469
-rw-r--r--kernel/kls_pnm/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_psd/Makefile.am9
-rw-r--r--kernel/kls_psd/fmt_codec_psd.cpp394
-rw-r--r--kernel/kls_psd/fmt_codec_psd_defs.h43
-rw-r--r--kernel/kls_psp/Makefile.am9
-rw-r--r--kernel/kls_psp/fmt_codec_psp.cpp635
-rw-r--r--kernel/kls_psp/fmt_codec_psp_defs.h249
-rw-r--r--kernel/kls_pxr/Makefile.am9
-rw-r--r--kernel/kls_pxr/fmt_codec_pxr.cpp173
-rw-r--r--kernel/kls_pxr/fmt_codec_pxr_defs.h25
-rw-r--r--kernel/kls_ras/Makefile.am9
-rw-r--r--kernel/kls_ras/fmt_codec_ras.cpp361
-rw-r--r--kernel/kls_ras/fmt_codec_ras_defs.h54
-rw-r--r--kernel/kls_rawrgb/Makefile.am9
-rw-r--r--kernel/kls_rawrgb/fmt_codec_rawrgb.cpp229
-rw-r--r--kernel/kls_rawrgb/fmt_codec_rawrgb_defs.h27
-rw-r--r--kernel/kls_sct/Makefile.am9
-rw-r--r--kernel/kls_sct/fmt_codec_sct.cpp232
-rw-r--r--kernel/kls_sct/fmt_codec_sct_defs.h51
-rw-r--r--kernel/kls_sgi/Makefile.am9
-rw-r--r--kernel/kls_sgi/fmt_codec_sgi.cpp341
-rw-r--r--kernel/kls_sgi/fmt_codec_sgi_defs.h50
-rw-r--r--kernel/kls_sun/Makefile.am9
-rw-r--r--kernel/kls_sun/fmt_codec_sun.cpp235
-rw-r--r--kernel/kls_sun/fmt_codec_sun_defs.h27
-rw-r--r--kernel/kls_svg/Makefile.am19
-rw-r--r--kernel/kls_svg/fmt_codec_png.cpp655
-rw-r--r--kernel/kls_svg/fmt_codec_png_defs.h27
-rw-r--r--kernel/kls_svg/ksquirrel-libs-svg2png.in20
-rw-r--r--kernel/kls_svg/libkls_svg.so.ui120
-rw-r--r--kernel/kls_tga/Makefile.am9
-rw-r--r--kernel/kls_tga/fmt_codec_tga.cpp411
-rw-r--r--kernel/kls_tga/fmt_codec_tga_defs.h70
-rw-r--r--kernel/kls_tiff/Makefile.am17
-rw-r--r--kernel/kls_tiff/fmt_codec_tiff.cpp298
-rw-r--r--kernel/kls_tiff/fmt_codec_tiff_defs.h27
-rw-r--r--kernel/kls_tiff/libkls_tiff.so.ui135
-rw-r--r--kernel/kls_ttf/Makefile.am19
-rw-r--r--kernel/kls_ttf/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_ttf/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_ttf/ftcommon.cpp1333
-rw-r--r--kernel/kls_ttf/ftcommon.h307
-rw-r--r--kernel/kls_ttf/ftview/Makefile.am9
-rw-r--r--kernel/kls_ttf/ftview/README1
-rw-r--r--kernel/kls_ttf/ftview/gblany.h133
-rw-r--r--kernel/kls_ttf/ftview/gblblit.cpp318
-rw-r--r--kernel/kls_ttf/ftview/gblblit.h82
-rw-r--r--kernel/kls_ttf/ftview/gblcolor.h56
-rw-r--r--kernel/kls_ttf/ftview/gblender.cpp381
-rw-r--r--kernel/kls_ttf/ftview/gblender.h216
-rw-r--r--kernel/kls_ttf/ftview/gblhbgr.h74
-rw-r--r--kernel/kls_ttf/ftview/gblhrgb.h76
-rw-r--r--kernel/kls_ttf/ftview/gblvbgr.h76
-rw-r--r--kernel/kls_ttf/ftview/gblvrgb.h76
-rw-r--r--kernel/kls_ttf/ftview/graph.h653
-rw-r--r--kernel/kls_ttf/ftview/grblit.cpp2068
-rw-r--r--kernel/kls_ttf/ftview/grblit.h25
-rw-r--r--kernel/kls_ttf/ftview/grconfig.h9
-rw-r--r--kernel/kls_ttf/ftview/grevents.h117
-rw-r--r--kernel/kls_ttf/ftview/grfont.cpp373
-rw-r--r--kernel/kls_ttf/ftview/grfont.h17
-rw-r--r--kernel/kls_ttf/ftview/grobjs.cpp213
-rw-r--r--kernel/kls_ttf/ftview/grobjs.h182
-rw-r--r--kernel/kls_ttf/ftview/grtypes.h52
-rw-r--r--kernel/kls_ttf/ttf2pnm.cpp187
-rw-r--r--kernel/kls_utah/Makefile.am15
-rw-r--r--kernel/kls_utah/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_utah/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_utah/ksquirrel-libs-utah2ppm.in3
-rw-r--r--kernel/kls_wal/Makefile.am9
-rw-r--r--kernel/kls_wal/fmt_codec_wal.cpp172
-rw-r--r--kernel/kls_wal/fmt_codec_wal_defs.h42
-rw-r--r--kernel/kls_wal/q2pal.h266
-rw-r--r--kernel/kls_wbmp/Makefile.am9
-rw-r--r--kernel/kls_wbmp/fmt_codec_wbmp.cpp278
-rw-r--r--kernel/kls_wbmp/fmt_codec_wbmp_defs.h37
-rw-r--r--kernel/kls_wmf/Makefile.am9
-rw-r--r--kernel/kls_wmf/fmt_codec_wmf.cpp150
-rw-r--r--kernel/kls_wmf/fmt_codec_wmf_defs.h25
-rw-r--r--kernel/kls_wmf/wmf2mem.cpp361
-rw-r--r--kernel/kls_xbm/Makefile.am9
-rw-r--r--kernel/kls_xbm/fmt_codec_xbm.cpp219
-rw-r--r--kernel/kls_xbm/fmt_codec_xbm_defs.h48
-rw-r--r--kernel/kls_xcf/Makefile.am18
-rw-r--r--kernel/kls_xcf/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_xcf/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_xcf/libkls_xcf.so.ui78
-rw-r--r--kernel/kls_xcf/xcf2pnm/Makefile.am5
-rw-r--r--kernel/kls_xcf/xcf2pnm/enums.c116
-rw-r--r--kernel/kls_xcf/xcf2pnm/enums.h98
-rw-r--r--kernel/kls_xcf/xcf2pnm/flatspec.c370
-rw-r--r--kernel/kls_xcf/xcf2pnm/flatten.c689
-rw-r--r--kernel/kls_xcf/xcf2pnm/flatten.h77
-rw-r--r--kernel/kls_xcf/xcf2pnm/io-unix.c176
-rw-r--r--kernel/kls_xcf/xcf2pnm/options.i410
-rw-r--r--kernel/kls_xcf/xcf2pnm/pixels.c487
-rw-r--r--kernel/kls_xcf/xcf2pnm/pixels.h128
-rw-r--r--kernel/kls_xcf/xcf2pnm/scaletab.c42
-rw-r--r--kernel/kls_xcf/xcf2pnm/table.c263
-rw-r--r--kernel/kls_xcf/xcf2pnm/utils.c164
-rw-r--r--kernel/kls_xcf/xcf2pnm/xcf-general.c287
-rw-r--r--kernel/kls_xcf/xcf2pnm/xcf2pnm.c269
-rw-r--r--kernel/kls_xcf/xcf2pnm/xcf2pnm.oi41
-rw-r--r--kernel/kls_xcf/xcf2pnm/xcftools.h182
-rw-r--r--kernel/kls_xcur/Makefile.am9
-rw-r--r--kernel/kls_xcur/fmt_codec_xcur.cpp166
-rw-r--r--kernel/kls_xcur/fmt_codec_xcur_defs.h76
-rw-r--r--kernel/kls_xim/Makefile.am15
-rw-r--r--kernel/kls_xim/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_xim/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_xim/ksquirrel-libs-xim2ppm.in3
-rw-r--r--kernel/kls_xpm/Makefile.am17
-rw-r--r--kernel/kls_xpm/fmt_codec_xpm.cpp258
-rw-r--r--kernel/kls_xpm/fmt_codec_xpm_defs.h25
-rw-r--r--kernel/kls_xpm/rgbmap719
-rw-r--r--kernel/kls_xpm/xpm_utils.h103
-rw-r--r--kernel/kls_xwd/Makefile.am9
-rw-r--r--kernel/kls_xwd/fmt_codec_xwd.cpp214
-rw-r--r--kernel/kls_xwd/fmt_codec_xwd_defs.h27
-rw-r--r--kernel/ksquirrel-libs/Makefile.am8
-rw-r--r--kernel/ksquirrel-libs/fileio.cpp136
-rw-r--r--kernel/ksquirrel-libs/fmt_utils.cpp187
-rwxr-xr-xkernel/link24
-rwxr-xr-xkernel/plusx3
-rw-r--r--kernel/xpm/codec_avs.xpm34
-rw-r--r--kernel/xpm/codec_bmp.xpm34
-rw-r--r--kernel/xpm/codec_camera.xpm34
-rw-r--r--kernel/xpm/codec_cut.xpm34
-rw-r--r--kernel/xpm/codec_dds.xpm30
-rw-r--r--kernel/xpm/codec_dicom.xpm30
-rw-r--r--kernel/xpm/codec_djvu.xpm31
-rw-r--r--kernel/xpm/codec_dxf.xpm36
-rw-r--r--kernel/xpm/codec_eps.xpm30
-rw-r--r--kernel/xpm/codec_fig.xpm30
-rw-r--r--kernel/xpm/codec_fits.xpm30
-rw-r--r--kernel/xpm/codec_fli.xpm34
-rw-r--r--kernel/xpm/codec_gif.xpm34
-rw-r--r--kernel/xpm/codec_hdr.xpm34
-rw-r--r--kernel/xpm/codec_ico.xpm34
-rw-r--r--kernel/xpm/codec_iff.xpm34
-rw-r--r--kernel/xpm/codec_jbig.xpm34
-rw-r--r--kernel/xpm/codec_jpeg.xpm34
-rw-r--r--kernel/xpm/codec_jpeg2000.xpm34
-rw-r--r--kernel/xpm/codec_koala.xpm34
-rw-r--r--kernel/xpm/codec_lbm.xpm30
-rw-r--r--kernel/xpm/codec_leaf.xpm30
-rw-r--r--kernel/xpm/codec_lif.xpm34
-rw-r--r--kernel/xpm/codec_ljpeg.xpm29
-rw-r--r--kernel/xpm/codec_mac.xpm34
-rw-r--r--kernel/xpm/codec_mdl.xpm34
-rw-r--r--kernel/xpm/codec_mng.xpm34
-rw-r--r--kernel/xpm/codec_msp.xpm34
-rw-r--r--kernel/xpm/codec_mtv.xpm34
-rw-r--r--kernel/xpm/codec_neo.xpm30
-rw-r--r--kernel/xpm/codec_openexr.xpm34
-rw-r--r--kernel/xpm/codec_pcx.xpm34
-rw-r--r--kernel/xpm/codec_pi1.xpm30
-rw-r--r--kernel/xpm/codec_pi3.xpm30
-rw-r--r--kernel/xpm/codec_pict.xpm30
-rw-r--r--kernel/xpm/codec_pix.xpm34
-rw-r--r--kernel/xpm/codec_png.xpm34
-rw-r--r--kernel/xpm/codec_pnm.xpm34
-rw-r--r--kernel/xpm/codec_psd.xpm34
-rw-r--r--kernel/xpm/codec_psp.xpm30
-rw-r--r--kernel/xpm/codec_pxr.xpm34
-rw-r--r--kernel/xpm/codec_ras.xpm34
-rw-r--r--kernel/xpm/codec_rawrgb.xpm34
-rw-r--r--kernel/xpm/codec_sct.xpm34
-rw-r--r--kernel/xpm/codec_sgi.xpm34
-rw-r--r--kernel/xpm/codec_sun.xpm34
-rw-r--r--kernel/xpm/codec_svg.xpm34
-rw-r--r--kernel/xpm/codec_tga.xpm34
-rw-r--r--kernel/xpm/codec_tiff.xpm34
-rw-r--r--kernel/xpm/codec_ttf.xpm34
-rw-r--r--kernel/xpm/codec_utah.xpm34
-rw-r--r--kernel/xpm/codec_wal.xpm34
-rw-r--r--kernel/xpm/codec_wbmp.xpm34
-rw-r--r--kernel/xpm/codec_wmf.xpm34
-rw-r--r--kernel/xpm/codec_xbm.xpm34
-rw-r--r--kernel/xpm/codec_xcf.xpm30
-rw-r--r--kernel/xpm/codec_xcur.xpm34
-rw-r--r--kernel/xpm/codec_xim.xpm30
-rw-r--r--kernel/xpm/codec_xpm.xpm34
-rw-r--r--kernel/xpm/codec_xwd.xpm34
-rw-r--r--ksquirrellibs.pc.in11
-rw-r--r--patch-stamp0
-rwxr-xr-xreconfigure3
-rwxr-xr-xrequired-etch14
-rw-r--r--stamp-h.in0
-rw-r--r--subdirs2
477 files changed, 132020 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..ec7cb52
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Baryshev Dmitry aka Krasu <ksquirrel.iv@gmail.com> \ No newline at end of file
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..eb5bebf
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,58 @@
+* ksquirrel-libs is under GNU LIBRARY GENERAL PUBLIC LICENSE (see LICENSE), except the following parts:
+
+* JBIG library statically links against jbig-kit (which is under GPL, see LICENSE.GPL) by (C) Markus Kuhn
+* MNG dynamically links against libmng, see LICENSE.MNG for more
+* LJPEG library statically uses ljpg, see LICENSE.LJPEG for more
+* DDS plugin is taken from KImageIO plugin from kdelibs 3.4.0 (which is under GPL)
+* EPS plugin is taken from KImageIO plugin from kdelibs 3.4.0 (which is under LGPL)
+* PSP plugin is taken from DevIL (which is under LGPL)
+* TTF library dynamically links against libfreetype, and
+ statically uses ftview from ftdemos-2.1.10, there are no LICENSE issues
+ in ftdemos package, but it is still copyrighted
+ Copyright 1996-2000, 2003, 2004, 2005 by
+ (C) D. Turner, R.Wilhelm, and W. Lemberg
+* XCF library statically uses xcf2pnm (which is under GPL)
+* PNG library uses its own version of libpng to support APNG images, see LICENSE.PNG
+
+other issues:
+* DJVU library uses "ddjvu" executable (via fork) from http://djvu.sf.net
+* DXF library uses "vec2web" executable (via fork) from http://ribbonsoft.org
+* TIFF library dynamically links against libtiff
+* GIF library dynamically links against libungif
+* JPEG library dynamically links against libjpeg
+* PNG library dynamically links against libpng
+* WMF library dynamically links against libwmf
+* OPENEXR library dynamically links against OpenEXR libraries
+* JPEG2000 library dynamically links against jasper, most code in this library
+ was taken from jasper.c from jasper distribution, which is under JASPER LICENSE,
+ see LICENSE.JASPER for more
+* SVG library uses "rsvg-convert" executable (via fork)
+* CAMERA library installs its own dcraw version 8.79. dcraw is by (C) Dave Coffin,
+ which is free redistributable if no source code modification were applied:
+
+/*
+ dcraw.c -- Dave Coffin's raw photo decoder
+ Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
+
+ This is a command-line ANSI C program to convert raw photos from
+ any digital camera on any computer running any operating system.
+
+ No license is required to download and use dcraw.c. However,
+ to lawfully redistribute dcraw, you must either (a) offer, at
+ no extra charge, full source code* for all executable files
+ containing RESTRICTED functions, (b) distribute this code under
+ the GPL Version 2 or later, (c) remove all RESTRICTED functions,
+ re-implement them, or copy them from an earlier, unrestricted
+ Revision of dcraw.c, or (d) purchase a license from the author.
+
+ The functions that process Foveon images have been RESTRICTED
+ since Revision 1.237. All other code remains free for all uses.
+
+ *If you have not modified dcraw.c in any way, a link to my
+ homepage qualifies as "full source code".
+
+ $Revision: 1.394 $
+ $Date: 2007/11/04 02:18:54 $
+ */
+
+And here is dcraw home page: http://cybercom.net/~dcoffin/dcraw/
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..6217287
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,555 @@
+ksquirrel-0.8.0 and ksquirrel-libs-0.8.0
+****************************************
+* new runtime options:
+ --nodirectorybasket
+ --noimagebasket
+ --nocategories
+ --nomountview
+* added Konqueror intergation module
+* added printing feature in image window
+* added codec manager, which will allow to
+ enable/disable image codecs (requires root password)
+* fixed licensing issues in source code
+* fixed MIME types in .desktop files
+* time counting in image window is more fair
+
+ksquirrel-libs:
+* added EPS, PSP
+* bugfix in PNM decoder on P3 PNMs
+* bugfix in CAMERA codec, when KSquirrel couldn't open raw fotos
+
+ksquirrel-0.7.5
+****************
+* more bugfixes in tabs
+* more improvements in selection rectangle in image window
+* selection rectangle is now drawn by OpenGL
+* saving to clipboard now doesn't mix red and blue channels
+* other small bugfixes
+* added translations: Turkish, Polish, Italian, British, Ukranian, Czech
+
+ksquirrel-0.7.4 (bugfix release)
+********************************
+* filtering and color balance in image window doesn't loose rotation angle
+* saving in image window doesn't loose rotation angle (flipping is still lost)
+* prevent autoresizing when tab count is 1
+* external tools for non-local URLs now work
+ (but not all programs accepts URLs, GQview for example)
+* external tools in image window now don't depend on navigator
+* navigator now has focus at startup
+* slider is changed when switching between tabs
+
+ksquirrel-0.7.3 and ksquirrel-libs-0.7.3
+*****************************************
+* command line arguments now work better
+* improvements in preview window
+* cusomizable double click in image window
+* select a region in image window and press Y to crop image
+* added tabs in image window (off by default) with Opera-like navigation
+* 100% zoom now doesn't use linear interpolation
+ (image is displayed "as is")
+* added service menu for Dolphin
+* added German translation
+
+ksquirrel-libs:
+* added DDS
+* JPEG2000 decoder is much faster now
+
+ksquirrel-0.7.2
+****************
+* lazy thumbnail generation now can generate additional rows
+* improvements in treeview
+* F10 to repeat last operation with selected files (copy/move/link)
+* it is highly recommended that you won't have FAM running,
+ see http://oss.sgi.com/bugzilla/show_bug.cgi?id=158 for more
+* Added folder basket
+
+ksquirrel-libs:
+* SVG codec now uses rsvg-convert
+* fixed segfault in GIF codec (in rare cases)
+* added DICOM (requires medcon)
+* added APNG (see http://wiki.mozilla.org/APNG_Specification, http://en.wikipedia.org/wiki/APNG)
+
+ksquirrel-0.7.1try5
+*********************
+* lazy thumbnail generation (like in DigiKam)
+* single click to highlight file, double click
+ to open
+* drag operation now can show number of dragged files
+ and first two thumbnails
+* fixed problems with file naming in converter and image window
+
+ksquirrel-0.7.1try4
+*********************
+* thumbnail loader now uses EXIF thumbnails if present
+* thumbnail rotation using exif
+* small fixes in thumbnail loader
+* small fixes thumbnail cache master
+
+ksquirrel-0.7.1try3
+********************
+* context menu in folder tree
+* folder tree now accepts drops
+* previous directory now selected during navigating
+* current page in sidebar is now saved
+* "Show hidden files" is also saved
+* Sorting order is also saved :)
+
+ksquirrel-0.7.1 and ksquirrel-libs-0.7.1
+******************************************
+
+ksquirrel:
+* context menu in file manager now have proper content (it worked in KDE 3.3, but in 3.5 it didn't)
+* kio-slaves support (including smb:/, tar:/ etc.)
+* archive extractor now uses kio-slaves (see previous). In general, it supports
+ zip, ar, tar.gz, tar.bz2, iso, rar, 7zip. To add support of rar and 7zip please install
+ kio_rar and kio_p7zip (search http://kde-apps.org)
+* thumbnail creation on non-local filesystems (for ex. smb:/ or tar:/)
+* statusbar improvements
+* hotkeys in image window now don't depend on current keyboard layout
+* history combobox now shows mime types
+* bugfixes in slideshow
+* new thumbnails' cache directory. Please remove old thumbnails from ~/.ksquirrel/thumbnails
+* image rotation using EXIF in thumbnail loader and image viewer
+* KIPI plugins now could be loaded on demand
+* F2 to rename files
+* thumbnail loader now corresponds thumbnail spec from freedesktop.org
+* other small bugfixes
+
+ksquirrel-libs:
+* added XFIG (transfig package is required)
+* added Degas PI3
+* TTF codec is designed for freetype 2.2.1 (it should work at least in Debian Etch)
+* CAMERA codec now uses dcraw v8.77 without modifications, which doesn't violate dcraw license
+* bugfixes in scripts
+
+ksquirrel-0.7.0try5
+*********************
+* navigator is now hidden when running with file argument
+
+ksquirrel-0.7.0try4
+*********************
+* fixed file selection when passing filename through command line
+
+ksquirrel-0.7.0try3
+*********************
+* animated widget in toolbar now can be disabled (Options->Main)
+* splash screen security improvements
+
+ksquirrel-0.7.0try2
+*********************
+* file path via command line parameter now works, e.g.
+ # ksquirrel /home/me/1.png
+* new autoconf test for OpenGL
+* small fix in image window toolbar (in 'Selection' popup menu)
+* fixed toolbar height in image window
+
+ksquirrel-0.7.0 and ksquirrel-libs-0.7.0
+********************************************
+
+ksquirrel:
+* filtering using selection is now available in image window
+* fixed flicker of thumbnail loading progressbar
+* fixed segfault on directory execution with "Return" button
+* RAR archives are now supported ("unrar" program is required)
+* fixed -l option
+* fixed crashing when no image plugins were found
+
+ksquirrel-0.7.0-pre2 and ksquirrel-libs-0.7.0-pre2
+********************************************
+
+This is last preview release.
+
+ksquirrel:
+* multiple directory view: Shift+click to recursively toggle current
+ item and all subitems; Ctrl+click to recursively set current
+ item and all subitems on; Alt+click to recursively set current
+ item and all subitems off
+* GQView mode removed till better times
+* added preview widget
+* new slideshow
+* bugfixes in slideshow mechanism
+* bugfix in mouse clicking (in list view and icon view)
+* current image now can be filtered (filetring using current selection will be available in 0.7.0)
+
+ksquirrel-libs:
+* added IFF, MAC, PICT, PI1, XIM, UTAH, LEAF, NEO (via NetPBM package)
+* small fix in configure.ac
+
+ksquirrel-0.7.0-pre1 and ksquirrel-libs-0.7.0-pre1
+********************************************
+ksquirrel:
+* added KIPI support
+* multiple directory view
+* automatic image fit in image window
+* some codecs now have options (DjVu, SVG, CAMERA...). Visit Plugins information dialog.
+* edit tools removed. use KIPI instead :) Convertion tool is still available
+* current image can be placed to clipboard
+* current images can be "saved as..."
+* bugfixes in "GQView" mode
+* mount view now can mount/unmount
+* thumbnail loading now ~15% faster
+* improvements in interface switching
+* sidebar: added image basket
+* sidebar: removed file actions (use context menu in navigator)
+* new DCOP parameters, see README
+* bugfixes
+
+ksquirrel-libs:
+* fixed segfault on GIF and some other libraries on some systems
+* CAMERA codec now uses dcraw 8.61
+* added settings support to CAMERA, SVG
+* added DjVu (just single page via settings).
+* added AutoCAD DXF (+settings)
+* added GIMP XCF (+settings)
+* small fixes in configure script
+* configure output now more informatible
+
+ksquirrel-0.6.3 and ksquirrel-libs-0.6.3
+********************************************
+
+ksquirrel:
+* interface improvements, now KSquirrel can look like GQview
+* small fix in reloading libraries from disk
+* added categories
+
+ksquirrel-0.6.2 and ksquirrel-libs-0.6.2
+********************************************
+ksquirrel and ksquirrel-libs now should correspond Debian policy.
+
+ksquirrel-libs:
+* some changes in API
+
+ksquirrel:
+* fixed segfault if the file format is not supported
+* new option: "Don't show tooltips when the main window is inactive"
+* "L" key ("Ignore, if the image is less than window") in image window now works
+* added Russian handbook
+* single-page images now eat less memory
+
+ksquirrel-0.6.1: bugfix release, minor changes
+*****************************************************
+
+ksquirrel:
+* updated .desktop files. MIME types inserted.
+* "Nice" zoom now default zoom type
+* "OpenGL information" moved to separate dialog
+* "./configure.gnu --disable-ksmall" to disable ksquirrel-small in compile time
+* small fix in rotate dialog, pixmap now erased correctly
+
+ksquirrel-libs:
+* some codecs are disabled as buggy (use --enable-devel to enable them)
+* ksquirrel-libs now installs development library and header files. Now ksquirel-libs
+ must be installed BEFORE KSquirrel.
+* updated documentation
+
+ksquirrel-0.6.0-final and ksquirrel-libs-0.6.0-final
+************************************************************
+
+ksquirrel:
+* small fix in animating mechanism
+* fixed F1/F4 bug in image window (only in pre9)
+* fixed small memory leak
+* closing image window now stops slideshow (if running)
+* fixed flicker in image window in fullscreen state with hidden toolbar
+* help widget now saves current page
+* fixes in help widget
+* If the image is broken, "broken" image will appear (like in GQview)
+* image window: right click = context menu, middle click = toggle fullscreen,
+ left click = start drag, left click+SHIFT = select zoom area
+* small fix in maximum/minimum zoom
+* improved Xinerama support (I hope)
+* small improvements in file manager
+* added new options:
+ - show images progressively
+ - hide toolbar in fullscreen
+ - ability to choose number of image pages to be loaded (in edit tools too)
+* added sidebar with
+ - file/image actions
+ - file tree
+ - view of currently mounted partitions
+* small memory optimizations in file manager
+* changing thumbnails' size now a little bit faster
+* fixed small bug in DCOP connection, which could cause strange behaviour of file manager
+* menu layout changes
+* small fix in version checker
+* small fix in setting background image in image window
+* new toolbar in image window
+* fixes in external tools
+* saving geometry now works properly
+* CTRL+T to recreate selected thumbnails + bugfixes
+* code cleanups, comments
+
+ksquirrel-libs:
+* SVG: added ".svgz" extension
+* MNG: small fix in data types
+* KOALA: small fix in bitdepth (bitdepth was always '0')
+
+ksquirrel-0.6.0-pre9 and ksquirrel-libs 0.6.0-pre9
+************************************************************
+
+ksquirrel:
+* small fixes in manual pages
+* library loader now doesn't check +x permissions
+* --enable-final for configure now works
+* ksquirrel-small: bugfixes
+* filter tool: added red-eye removal
+* filter tool: small fix in pixmap updating
+* edit tools: improvements in preview image
+* edit tools: small fix with alpha channel for preview image
+* experimental "Nice zoom" ('N' to toggle)
+* new toolbar in image window
+* improvements in loading mechanism, now KSquirrel will store only ONE frame in video memory. Is doesn't depend on whether image is animated or not
+* ksquirrel-small now doesn't share settings with KSquirrel, but some settings (like zoom limit, background color etc. are still shared (and read-only))
+* fixed small memory leak
+* code cleanups
+
+ksquirrel-libs:
+* XCUR: fixed segfault
+* PNM: small fix (on pgm images)
+* SGI: small improvements
+* CAMERA: new file extensions added
+* added font support (ttf, pfa, pfb...)
+* added MNG, JNG (reading)
+* added PXR (reading)
+* added JBIG (slow, reading))
+* code cleanups
+* no more static libraries. Now SVG, GIF, OPENEXR, WMF and JPEG2000 are optional.
+[from 0.6.0-pre8 u1 + new ones]
+* new options for configure script:
+ --disable-gif
+ --disable-camera
+ --disable-wmf
+ --disable-svg
+ --disable-openexr
+ --disable-jpeg2000
+ --disable-mng
+ --disable-ttf
+
+ksquirrel-0.6.0-pre8 and ksquirrel-libs 0.6.0-pre7
+************************************************************
+
+ksquirrel:
+* edit tools: fixed bug in writing images
+* edit tools: preview image now works
+* edit tools: new writing options
+* filter tool: added 20 filters
+* resize tool: removed all previous resize methods, added new ones: Box, Triangle, Bell, B-Spline, Lanczos3, Mitchell
+* some interface changes in filter tool
+* code cleanups
+* source code now hardly commented
+* added man page
+* added new binary: ksquirrel-small. It is "light" version of KSquirrel - without filemanager, External tools, Filters,
+ Edit tools etc. It takes only one command line argument - path to file. For example:
+
+[localhost@krasu]$ ksquirrel-small /mnt/c/images/cat.png
+
+ksquirrel-libs:
+* internal changes
+
+ksquirrel-0.6.0-pre7 and ksquirrel-libs-0.6.0-pre6
+************************************************************
+
+ksquirrel:
+* fixed segfault when printing multipaged images
+* fixed small bug in "Recreate selected thumbnails" action in thumbnail view
+* fixed wrong header naming in "External tools" menu
+* fixed small bug in print tool, in "Alignment" frame
+* fixed bug with size() of version checker
+* fixed compile problems on some Qt versions, which don't support STL (like Slackware's one)
+* added filter tool (only "Negative" and "swap RGB" are currently supported, new filters coming soon)
+* added slideshow and advanced slideshow (Ctrl+S, Ctrl+Alt+S)
+* added mc-like file selection with '+' and '-'
+* added "Select All" and "Deselect" actions in menu
+* added some new options
+* added unique application support (KSquirrel now can have only one running instance)
+* print tool: "Custom fill" now works
+* print tool: added transparency support
+* now you needn't delete old config file - KSquirrel will do it for you
+* edit tools now look like simple wizards (hope TiamaT will draw new squirrels soon...)
+* libraries information was moved from Options to "Plugins information" dialog
+* some menu layout changes
+* code cleanups
+
+ksquirrel-libs:
+* some changes in API
+* added MTV Ray-Tracer (reading, writing)
+* added AVS X (reading, writing)
+* added PNM (writing)
+* LIF: many bugfixes
+* SVG: removed useless "-lfontconfig" dependency, which could create compile problems on some systems (like Slackware)
+* PNG: fixed autoconf problems on some systems (like Slackware)
+
+ksquirrel-0.6.0-pre6 and ksquirrel-libs-0.6.0-pre5
+************************************************************
+
+ksquirrel:
+* resize tool now works (four resize methods: nearest, bilinear, tiles, hyper)
+* colorize tool now works
+* rotate tool now works (has some small bugs in algorithm)
+* print tool now partially works (only "One image per one page")
+
+ksquirrel-libs:
+* added JPEG2000 (reading)
+* added OpenEXR (reading)
+* added Quake2 WAL texture (reading)
+* added HalfLife model (reading)
+* added KOALA (reading)
+* added HDR (reading)
+* added LIF (reading)
+* added SCT (reading)
+* CUT decoder now not-alpha
+
+ksquirrel-0.6.0-pre5
+************************************************************
+
+ksquirrel:
+* added DCOP interface, which was removed in early 0.2.8 :) Check README for list of parameters
+* new version checker (old one removed)
+
+
+ksquirrel-0.6.0-pre4
+************************************************************
+
+ksquirrel:
+* new autoconf test for GL library. old one could fail on some systems.
+* image window: some changes in toolbar and context menu.
+
+
+ksquirrel-0.6.0-pre3
+************************************************************
+
+ksquirrel:
+* small fix in tootips for thumbnails
+* small fix in toolbar in image window
+* some changes in main toolbar
+* resize, rotate, colorize and print tools are available in preview mode
+ (will read, but won't write images)
+* added thumbnail cache manipulator
+
+ksquirrel-libs:
+* some changes in API. pre2 and pre3 are not compatible.
+* added SVG (reading, requires libxml2, freetype)
+* TGA: small fix (in v0.7.1 flipping was ON by default, in v0.7.2 flipping is determined by image header)
+* XPM: small fix in decoding mechanism
+* new mime icons
+
+
+ksquirrel-0.6.0-pre2
+************************************************************
+
+* please, remove old config file ~/.kde/share/config/ksquirrelrc and old libraries before installation
+* some changes in thumbnail view
+
+ksquirrel-libs:
+* changed library path /usr/lib/squirrel =>/usr/lib/ksquirrel-libs
+* fully migrated to C++ (stdc++)
+* added WMF (reading)
+* added SUN Icon (reading)
+* added WBMP (reading)
+* added TIFF (writing)
+* added photos from different cameras (CRW, ...)
+* added some examples (QT, QT+OpenGL)
+
+
+ksquirrel-0.6.0-pre1
+************************************************************
+
+* moved back to Right Click = mouse selection, Middle Click = context menu
+* added file actions in Navigator - Copy, Paste, Cut, etc.
+* added -t option: find all supported images and create thumbnails. For example
+ # ksquirrel -t /home/ckult/images/
+* "External Tools" now based on .desktop files
+* fixed crashing when command line is not empty
+* improved Drag'n'Drop support
+* image converter now available (select files and press Ctrl+K), but not all libraries support write functions
+
+ksquirrel-libs:
+* added interface for write functions
+* added write features for PNG, JPEG, BMP
+* PNG: fixed problems with interlaced images, fixed memory leak
+* XPM: fixed problems with multiline comments
+* ICO: added support of bit depth 24 and 32
+* PSD: fixed problems with RGB images, that have 3 channels instead of 4
+* GIF: added comments support (comment extensions)
+* PNM: fixed problems with Windows-like line breaks (\r\n)
+
+
+ksquirrel-0.5.0(final)
+******************************************************************
+
+* added nice tickmarks around the image (press K to toggle)
+* Middle click (or 'M') for context menu
+* F5 to recreate selected thumbnails
+
+* fixed little repainting problem
+* fixed startup problem, if /usr/lib/squirrel doesn't exist.
+* fixed problem with making image window built-in/separate
+* fixed small problem with decoding corrupted files
+
+ksquirrel-libs:
+* GIF decoder is much better now (fixed problems with transparency)
+* added X cursors
+* added PSD(RGB,CMYK,Grayscale,Indexed)
+* added FLI Animation
+* added thumbnail generator for FLI, GIF
+* small fixes in PNM, BMP libraries
+
+
+ksquirrel-0.5.0-preview4
+******************************************************************
+
+critical/important:
+* fixed crushing on item execution (SIGALRM signal, or "Alarm clock")
+* fixed awful lines (http://ksquirrel.sf.net/IMG/errors.png)
+* support of multipaged images (GIF, ICO, etc.)
+* Now my e-mail is ksquirrel at tut.by
+* moved back to PNG thumbnails. Please, rm -rf ~/.ksquirrel/thumbnails/
+
+ksquirrel-libs:
+* GIF (beta, including animated)
+* interlaced PNG's
+* fixed random crushing on some PNGs
+* about 15 formats are done
+
+other:
+* some interface improvements
+* improvements in 'Image Properties'
+* new 'fullscreen' method (KDE-related)
+* "Quick Browser" now can be moved and resized
+* other small fixes
+
+>>> Remember that ksquirrel-libs-0.5.0-pre3 and pre4 ARE NOT compatible!
+
+
+ksquirrel-0.5.0-preview3 for KDE 3.2 and JPEG library for preview3
+******************************************************************
+
+Please be patient - preview3 contains only one library, anyway, it's just a preview.
+
+>> critical or important:
+* fixed wrong displaying of huge images (more than 2048x2048); now doesn't depend on GL_MAX_TEXTURE_SIZE =)
+* fixed crashing on thumbnail view
+* fixed awful memory leak, shame on myself !! =)
+* moved to JPEG thumbnails (remove old ones from ~/.ksquirrel/thumbnails !)
+* detecting images by content (like Trolltech's QImage)
+* removed "Look like ..." - useless stuff
+* please check README for new keyboard shortcuts.
+
+>> other:
+* now "make -f Makefile.dist" to recreate configure and other scripts
+* configure was generated with autoconf 2.59, Makefiles - with automake 1.8.5
+* fixed wrong url selection in treeview
+* fixed wrong gridX value selection in SQ_FileThumbView
+* fixed wrong filter selection on startup
+* added library's filters support
+* added pending thumbnails (sand-glass)
+* added extended thumbnails
+* added configurable zoom limit
+* added tooltips with thumbnail info
+* double click in Navigator opens current url in default browser
+* image displaying is now faster
+* determining archives by MIME, not by extension (._zip wasn't been handled :-(( )
+* some changes in 'Options' dialog
+* removed GL_LINEAR filter due to new displaying alghoritm
+* other small fixes.
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..28ba2ff
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,22 @@
+How to install 'ksquirrel-libs' package:
+
+ a) from sources
+ # tar jxfv ksquirrel-libs-0.8.0.tar.bz2
+ # cd ksquirrel-libs-0.8.0/
+ * # su -c './required-etch'
+ # ./configure.gnu (not ./configure !)
+ # make
+ # su -c 'make install'
+
+* For Debian Etch and Ubuntu Feisty only.
+ This will install all required packages with aptitude.
+
+ b) from binary packages
+RPM # rpm -ihv ksquirrel-libs-0.8.0.rpm
+TGZ # installpkg ksquirrel-libs-0.8.0.tgz
+DEB # dpkg -i ksquirrel-libs-0.8.0.deb
+
+--------------------------------------------------------------
+
+Note: You can pass all regular 'configure' parameters to configure.gnu.
+Note: Your automake version should be 1.8 or higher.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5797d01
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSE.GPL b/LICENSE.GPL
new file mode 100644
index 0000000..c13faf0
--- /dev/null
+++ b/LICENSE.GPL
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/LICENSE.JASPER b/LICENSE.JASPER
new file mode 100644
index 0000000..8975f6f
--- /dev/null
+++ b/LICENSE.JASPER
@@ -0,0 +1,50 @@
+JasPer License Version 2.0
+
+Copyright (c) 2001-2006 Michael David Adams
+Copyright (c) 1999-2000 Image Power, Inc.
+Copyright (c) 1999-2000 The University of British Columbia
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person (the
+"User") 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, 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:
+
+1. The above copyright notices and this permission notice (which
+includes the disclaimer below) shall be included in all copies or
+substantial portions of the Software.
+
+2. The name of a copyright holder shall not be used to endorse or
+promote products derived from the Software without specific prior
+written permission.
+
+THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
+LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
+"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 OF THIRD PARTY RIGHTS. IN NO
+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
+PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
+THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
+EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
+BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
+PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
+GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
+ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
+IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
+SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
+AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
+SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
+THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
+PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
+RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
+EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
diff --git a/LICENSE.LJPEG b/LICENSE.LJPEG
new file mode 100644
index 0000000..5fae625
--- /dev/null
+++ b/LICENSE.LJPEG
@@ -0,0 +1,79 @@
+Copyright (c) 1993 Cornell University, Kongji Huang
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for research purposes, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+
+Copyright (c) 1993 The Regents of the University of California, Brian
+C. Smith All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+IJG Copyright
+
+The authors make NO WARRANTY or representation, either express or
+implied, with respect to this software, its quality, accuracy,
+merchantability, or fitness for a particular purpose. This software is
+provided "AS IS", and you, its user, assume the entire risk as to its
+quality and accuracy.
+
+This software is copyright (C) 1991, 1992, Thomas G. Lane. All Rights
+Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to
+these conditions: (1) If any part of the source code for this software
+is distributed, then this README file must be included, with this
+copyright and no-warranty notice unaltered; and any additions,
+deletions, or changes to the original files must be clearly indicated
+in accompanying documentation. (2) If only executable code is
+distributed, then the accompanying documentation must state that "this
+software is based in part on the work of the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user
+accepts full responsibility for any undesirable consequences; the
+authors accept NO LIABILITY for damages of any kind.
+
+Permission is NOT granted for the use of any IJG author's name or
+company name in advertising or publicity relating to this software or
+products derived from it. This software may be referred to only as
+"the Independent JPEG Group's software".
+
+We specifically permit and encourage the use of this software as the
+basis of commercial products, provided that all warranty or liability
+claims are assumed by the product vendor.
diff --git a/LICENSE.MNG b/LICENSE.MNG
new file mode 100644
index 0000000..bae3a82
--- /dev/null
+++ b/LICENSE.MNG
@@ -0,0 +1,56 @@
+/* ************************************************************************** */
+/* * * */
+/* * COPYRIGHT NOTICE: * */
+/* * * */
+/* * Copyright (c) 2000 Gerard Juyn (gerard@libmng.com) * */
+/* * [You may insert additional notices after this sentence if you modify * */
+/* * this source] * */
+/* * * */
+/* * For the purposes of this copyright and license, "Contributing Authors" * */
+/* * is defined as the following set of individuals: * */
+/* * * */
+/* * Gerard Juyn * */
+/* * * */
+/* * The MNG Library is supplied "AS IS". The Contributing Authors * */
+/* * disclaim all warranties, expressed or implied, including, without * */
+/* * limitation, the warranties of merchantability and of fitness for any * */
+/* * purpose. The Contributing Authors assume no liability for direct, * */
+/* * indirect, incidental, special, exemplary, or consequential damages, * */
+/* * which may result from the use of the MNG Library, even if advised of * */
+/* * the possibility of such damage. * */
+/* * * */
+/* * Permission is hereby granted to use, copy, modify, and distribute this * */
+/* * source code, or portions hereof, for any purpose, without fee, subject * */
+/* * to the following restrictions: * */
+/* * * */
+/* * 1. The origin of this source code must not be misrepresented; * */
+/* * you must not claim that you wrote the original software. * */
+/* * * */
+/* * 2. Altered versions must be plainly marked as such and must not be * */
+/* * misrepresented as being the original source. * */
+/* * * */
+/* * 3. This Copyright notice may not be removed or altered from any source * */
+/* * or altered source distribution. * */
+/* * * */
+/* * The Contributing Authors specifically permit, without fee, and * */
+/* * encourage the use of this source code as a component to supporting * */
+/* * the MNG and JNG file format in commercial products. If you use this * */
+/* * source code in a product, acknowledgment would be highly appreciated. * */
+/* * * */
+/* ************************************************************************** */
+/* * * */
+/* * Parts of this software have been adapted from the libpng package. * */
+/* * Although this library supports all features from the PNG specification * */
+/* * (as MNG descends from it) it does not require the libpng package. * */
+/* * It does require the zlib library and optionally the IJG jpeg library, * */
+/* * and/or the "little-cms" library by Marti Maria (depending on the * */
+/* * inclusion of support for JNG and Full-Color-Management respectively. * */
+/* * * */
+/* * This library's function is primarily to read and display MNG * */
+/* * animations. It is not meant as a full-featured image-editing * */
+/* * component! It does however offer creation and editing functionality * */
+/* * at the chunk level. * */
+/* * (future modifications may include some more support for creation * */
+/* * and or editing) * */
+/* * * */
+/* ************************************************************************** */
diff --git a/LICENSE.PNG b/LICENSE.PNG
new file mode 100644
index 0000000..a93dc98
--- /dev/null
+++ b/LICENSE.PNG
@@ -0,0 +1,109 @@
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.20, September 8, 2007, are
+Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+ Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+September 8, 2007
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..87754d8
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,24 @@
+SUBDIRS = kernel doc
+
+AUTOMAKE_OPTIONS = foreign
+
+pkgconfigdir = ${libdir}/pkgconfig
+pkgconfig_DATA = ksquirrellibs.pc
+
+$(top_srcdir)/subdirs:
+ cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
+
+$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
+ @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
+
+MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files
+
+dist-hook:
+ cd $(top_distdir) && perl admin/am_edit -padmin
+ cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs
+
+EXTRA_DIST = examples/w3.bmp examples/qtapp/main.cpp examples/qtapp/myqt.cpp examples/qtapp/myqt.h examples/qtapp/qtapp.pro \
+examples/qtgl/main.cpp examples/qtgl/myqgl.cpp examples/qtgl/myqgl.h examples/qtgl/qtgl.pro ksquirrellibs.pc.in required-etch \
+description-pak admin/acinclude.m4.in admin/config.guess admin/config.sub admin/depcomp admin/Doxyfile.global admin/ltmain.sh admin/mkinstalldirs \
+admin/am_edit admin/compile admin/config.pl admin/configure.in.bot.end admin/cvs.sh admin/install-sh admin/Makefile.common admin/nmcheck \
+admin/bcheck.pl admin/conf.change.pl admin/configure.in.min admin/debianrules admin/Doxyfile.am admin/libtool.m4.in admin/missing admin/ylwrap ChangeLog admin/config.rpath \ No newline at end of file
diff --git a/Makefile.dist b/Makefile.dist
new file mode 100644
index 0000000..be59a86
--- /dev/null
+++ b/Makefile.dist
@@ -0,0 +1,14 @@
+all:
+ @echo "This Makefile is only for the CVS repository"
+ @echo "This will be deleted before making the distribution"
+ @echo ""
+ @if test ! -d admin; then \
+ echo "Please recheckout this module!" ;\
+ echo "for cvs: use checkout once and after that update again" ;\
+ echo "for cvsup: checkout kde-common from cvsup and" ;\
+ echo " link kde-common/admin to ./admin" ;\
+ exit 1 ;\
+ fi
+ $(MAKE) -f admin/Makefile.common cvs
+
+.SILENT:
diff --git a/README b/README
new file mode 100644
index 0000000..6fc58c3
--- /dev/null
+++ b/README
@@ -0,0 +1,41 @@
+Important
+---------
+* if you you want JPEG, PNG and TIFF support,
+ please install libpng, libjpeg and libtiff.
+* XWD library requires X11/XWDFile.h.
+* WMF library requires freetype2, libxml2
+* SVG library requires rsvg-convert
+* MNG library requires libmng
+* TTF library requires libfreetype >= 2.1.9
+* GIF library requires libungif
+* All this packages plus -devel packages
+
+* DXF library requires vec2web installed
+* DJVU library requires "ddjvu" installed
+* NEO, IFF, PICT and some other libraries require NetPBM installed
+
+About
+-----
+* ksquirrel-libs is a set of image codecs.
+* It contains regular libraries for KSquirrel.
+* It contains different image decoders for JPEG, PNG, BMP, TIFF, PSD, GIF etc.
+ You can use ksquirrel-libs in other projects, just write your
+ own mechanism that could use the libraries.
+* You can find latest version of ksquirrel-libs at http://ksquirrel.sf.net.
+* You can find some interesting examples in "examples" directory
+ qgl - using ksquirrel-libs with Qt and OpenGL (QGLWidget)
+ qtapp - using ksquirrel-libs with Qt (QLabel)
+
+ To compile them cd to "examples" and run make
+
+* You can simply use it in your viewer or any other program
+* rawrgb library is a good example how to write new codec
+
+Version
+-------
+Current version: see VERSION
+
+Copyrights
+----------
+
+see COPYING \ No newline at end of file
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..8adc70f
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.8.0 \ No newline at end of file
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..a1b3edf
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,11864 @@
+## -*- autoconf -*-
+
+dnl This file is part of the KDE libraries/packages
+dnl Copyright (C) 1997 Janos Farkas (chexum@shadow.banki.hu)
+dnl (C) 1997,98,99 Stephan Kulow (coolo@kde.org)
+
+dnl This file is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Library General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2 of the License, or (at your option) any later version.
+
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Library General Public License for more details.
+
+dnl You should have received a copy of the GNU Library General Public License
+dnl along with this library; see the file COPYING.LIB. If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+dnl Boston, MA 02110-1301, USA.
+
+dnl IMPORTANT NOTE:
+dnl Please do not modify this file unless you expect your modifications to be
+dnl carried into every other module in the repository.
+dnl
+dnl Single-module modifications are best placed in configure.in for kdelibs
+dnl and kdebase or configure.in.in if present.
+
+# KDE_PATH_X_DIRECT
+dnl Internal subroutine of AC_PATH_X.
+dnl Set ac_x_includes and/or ac_x_libraries.
+AC_DEFUN([KDE_PATH_X_DIRECT],
+[
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+AC_TRY_CPP([#include <$x_direct_test_include>],
+[# We can compile using X headers with no special include directory.
+ac_x_includes=],
+[# Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done])
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+AC_TRY_LINK([#include <X11/Intrinsic.h>], [${x_direct_test_function}(1)],
+[LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=],
+[LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib${kdelibsuff}/` \
+ /usr/X11/lib${kdelibsuff} \
+ /usr/X11R6/lib${kdelibsuff} \
+ /usr/X11R5/lib${kdelibsuff} \
+ /usr/X11R4/lib${kdelibsuff} \
+ \
+ /usr/lib${kdelibsuff}/X11 \
+ /usr/lib${kdelibsuff}/X11R6 \
+ /usr/lib${kdelibsuff}/X11R5 \
+ /usr/lib${kdelibsuff}/X11R4 \
+ \
+ /usr/local/X11/lib${kdelibsuff} \
+ /usr/local/X11R6/lib${kdelibsuff} \
+ /usr/local/X11R5/lib${kdelibsuff} \
+ /usr/local/X11R4/lib${kdelibsuff} \
+ \
+ /usr/local/lib${kdelibsuff}/X11 \
+ /usr/local/lib${kdelibsuff}/X11R6 \
+ /usr/local/lib${kdelibsuff}/X11R5 \
+ /usr/local/lib${kdelibsuff}/X11R4 \
+ \
+ /usr/X386/lib${kdelibsuff} \
+ /usr/x386/lib${kdelibsuff} \
+ /usr/XFree86/lib${kdelibsuff}/X11 \
+ \
+ /usr/lib${kdelibsuff} \
+ /usr/local/lib${kdelibsuff} \
+ /usr/unsupported/lib${kdelibsuff} \
+ /usr/athena/lib${kdelibsuff} \
+ /usr/local/x11r5/lib${kdelibsuff} \
+ /usr/lpp/Xamples/lib${kdelibsuff} \
+ /lib/usr/lib${kdelibsuff}/X11 \
+ \
+ /usr/openwin/lib${kdelibsuff} \
+ /usr/openwin/share/lib${kdelibsuff} \
+ ; \
+do
+dnl Don't even attempt the hair of trying to link an X program!
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done])
+fi # $ac_x_libraries = NO
+])
+
+
+dnl ------------------------------------------------------------------------
+dnl Find a file (or one of more files in a list of dirs)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_FIND_FILE],
+[
+$3=NO
+for i in $2;
+do
+ for j in $1;
+ do
+ echo "configure: __oline__: $i/$j" >&AC_FD_CC
+ if test -r "$i/$j"; then
+ echo "taking that" >&AC_FD_CC
+ $3=$i
+ break 2
+ fi
+ done
+done
+])
+
+dnl KDE_FIND_PATH(program-name, variable-name, list-of-dirs,
+dnl if-not-found, test-parameter, prepend-path)
+dnl
+dnl Look for program-name in list-of-dirs+$PATH.
+dnl If prepend-path is set, look in $PATH+list-of-dirs instead.
+dnl If found, $variable-name is set. If not, if-not-found is evaluated.
+dnl test-parameter: if set, the program is executed with this arg,
+dnl and only a successful exit code is required.
+AC_DEFUN([KDE_FIND_PATH],
+[
+ AC_MSG_CHECKING([for $1])
+ if test -n "$$2"; then
+ kde_cv_path="$$2";
+ else
+ kde_cache=`echo $1 | sed 'y%./+-%__p_%'`
+
+ AC_CACHE_VAL(kde_cv_path_$kde_cache,
+ [
+ kde_cv_path="NONE"
+ kde_save_IFS=$IFS
+ IFS=':'
+ dirs=""
+ for dir in $PATH; do
+ dirs="$dirs $dir"
+ done
+ if test -z "$6"; then dnl Append dirs in PATH (default)
+ dirs="$3 $dirs"
+ else dnl Prepend dirs in PATH (if 6th arg is set)
+ dirs="$dirs $3"
+ fi
+ IFS=$kde_save_IFS
+
+ for dir in $dirs; do
+ if test -x "$dir/$1"; then
+ if test -n "$5"
+ then
+ evalstr="$dir/$1 $5 2>&1 "
+ if eval $evalstr; then
+ kde_cv_path="$dir/$1"
+ break
+ fi
+ else
+ kde_cv_path="$dir/$1"
+ break
+ fi
+ fi
+ done
+
+ eval "kde_cv_path_$kde_cache=$kde_cv_path"
+
+ ])
+
+ eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\""
+
+ fi
+
+ if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then
+ AC_MSG_RESULT(not found)
+ $4
+ else
+ AC_MSG_RESULT($kde_cv_path)
+ $2=$kde_cv_path
+
+ fi
+])
+
+AC_DEFUN([KDE_MOC_ERROR_MESSAGE],
+[
+ AC_MSG_ERROR([No Qt meta object compiler (moc) found!
+Please check whether you installed Qt correctly.
+You need to have a running moc binary.
+configure tried to run $ac_cv_path_moc and the test didn't
+succeed. If configure shouldn't have tried this one, set
+the environment variable MOC to the right one before running
+configure.
+])
+])
+
+AC_DEFUN([KDE_UIC_ERROR_MESSAGE],
+[
+ AC_MSG_WARN([No Qt ui compiler (uic) found!
+Please check whether you installed Qt correctly.
+You need to have a running uic binary.
+configure tried to run $ac_cv_path_uic and the test didn't
+succeed. If configure shouldn't have tried this one, set
+the environment variable UIC to the right one before running
+configure.
+])
+])
+
+
+AC_DEFUN([KDE_CHECK_UIC_FLAG],
+[
+ AC_MSG_CHECKING([whether uic supports -$1 ])
+ kde_cache=`echo $1 | sed 'y% .=/+-%____p_%'`
+ AC_CACHE_VAL(kde_cv_prog_uic_$kde_cache,
+ [
+ cat >conftest.ui <<EOT
+ <!DOCTYPE UI><UI version="3" stdsetdef="1"></UI>
+EOT
+ ac_uic_testrun="$UIC_PATH -$1 $2 conftest.ui >/dev/null"
+ if AC_TRY_EVAL(ac_uic_testrun); then
+ eval "kde_cv_prog_uic_$kde_cache=yes"
+ else
+ eval "kde_cv_prog_uic_$kde_cache=no"
+ fi
+ rm -f conftest*
+ ])
+
+ if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then
+ AC_MSG_RESULT([yes])
+ :
+ $3
+ else
+ AC_MSG_RESULT([no])
+ :
+ $4
+ fi
+])
+
+
+dnl ------------------------------------------------------------------------
+dnl Find the meta object compiler and the ui compiler in the PATH,
+dnl in $QTDIR/bin, and some more usual places
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_PATH_QT_MOC_UIC],
+[
+ AC_REQUIRE([KDE_CHECK_PERL])
+ qt_bindirs=""
+ for dir in $kde_qt_dirs; do
+ qt_bindirs="$qt_bindirs $dir/bin $dir/src/moc"
+ done
+ qt_bindirs="$qt_bindirs /usr/bin /usr/X11R6/bin /usr/local/qt/bin"
+ if test ! "$ac_qt_bindir" = "NO"; then
+ qt_bindirs="$ac_qt_bindir $qt_bindirs"
+ fi
+
+ KDE_FIND_PATH(moc, MOC, [$qt_bindirs], [KDE_MOC_ERROR_MESSAGE])
+ if test -z "$UIC_NOT_NEEDED"; then
+ KDE_FIND_PATH(uic, UIC_PATH, [$qt_bindirs], [UIC_PATH=""])
+ if test -z "$UIC_PATH" ; then
+ KDE_UIC_ERROR_MESSAGE
+ exit 1
+ else
+ UIC=$UIC_PATH
+
+ if test $kde_qtver = 3; then
+ KDE_CHECK_UIC_FLAG(L,[/nonexistent],ac_uic_supports_libpath=yes,ac_uic_supports_libpath=no)
+ KDE_CHECK_UIC_FLAG(nounload,,ac_uic_supports_nounload=yes,ac_uic_supports_nounload=no)
+
+ if test x$ac_uic_supports_libpath = xyes; then
+ UIC="$UIC -L \$(kde_widgetdir)"
+ fi
+ if test x$ac_uic_supports_nounload = xyes; then
+ UIC="$UIC -nounload"
+ fi
+ fi
+ fi
+ else
+ UIC="echo uic not available: "
+ fi
+
+ AC_SUBST(MOC)
+ AC_SUBST(UIC)
+
+ UIC_TR="i18n"
+ if test $kde_qtver = 3; then
+ UIC_TR="tr2i18n"
+ fi
+
+ AC_SUBST(UIC_TR)
+])
+
+AC_DEFUN([KDE_1_CHECK_PATHS],
+[
+ KDE_1_CHECK_PATH_HEADERS
+
+ KDE_TEST_RPATH=
+
+ if test -n "$USE_RPATH"; then
+
+ if test -n "$kde_libraries"; then
+ KDE_TEST_RPATH="-R $kde_libraries"
+ fi
+
+ if test -n "$qt_libraries"; then
+ KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries"
+ fi
+
+ if test -n "$x_libraries"; then
+ KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries"
+ fi
+
+ KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH"
+ fi
+
+AC_MSG_CHECKING([for KDE libraries installed])
+ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5'
+
+if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_ERROR([your system fails at linking a small KDE application!
+Check, if your compiler is installed correctly and if you have used the
+same compiler to compile Qt and kdelibs as you did use now.
+For more details about this problem, look at the end of config.log.])
+fi
+
+if eval `KDEDIR= ./conftest 2>&5`; then
+ kde_result=done
+else
+ kde_result=problems
+fi
+
+KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log
+kde_have_all_paths=yes
+
+KDE_SET_PATHS($kde_result)
+
+])
+
+AC_DEFUN([KDE_SET_PATHS],
+[
+ kde_cv_all_paths="kde_have_all_paths=\"yes\" \
+ kde_htmldir=\"$kde_htmldir\" \
+ kde_appsdir=\"$kde_appsdir\" \
+ kde_icondir=\"$kde_icondir\" \
+ kde_sounddir=\"$kde_sounddir\" \
+ kde_datadir=\"$kde_datadir\" \
+ kde_locale=\"$kde_locale\" \
+ kde_cgidir=\"$kde_cgidir\" \
+ kde_confdir=\"$kde_confdir\" \
+ kde_kcfgdir=\"$kde_kcfgdir\" \
+ kde_mimedir=\"$kde_mimedir\" \
+ kde_toolbardir=\"$kde_toolbardir\" \
+ kde_wallpaperdir=\"$kde_wallpaperdir\" \
+ kde_templatesdir=\"$kde_templatesdir\" \
+ kde_bindir=\"$kde_bindir\" \
+ kde_servicesdir=\"$kde_servicesdir\" \
+ kde_servicetypesdir=\"$kde_servicetypesdir\" \
+ kde_moduledir=\"$kde_moduledir\" \
+ kde_styledir=\"$kde_styledir\" \
+ kde_widgetdir=\"$kde_widgetdir\" \
+ xdg_appsdir=\"$xdg_appsdir\" \
+ xdg_menudir=\"$xdg_menudir\" \
+ xdg_directorydir=\"$xdg_directorydir\" \
+ kde_result=$1"
+])
+
+AC_DEFUN([KDE_SET_DEFAULT_PATHS],
+[
+if test "$1" = "default"; then
+
+ if test -z "$kde_htmldir"; then
+ kde_htmldir='\${datadir}/doc/HTML'
+ fi
+ if test -z "$kde_appsdir"; then
+ kde_appsdir='\${datadir}/applnk'
+ fi
+ if test -z "$kde_icondir"; then
+ kde_icondir='\${datadir}/icons'
+ fi
+ if test -z "$kde_sounddir"; then
+ kde_sounddir='\${datadir}/sounds'
+ fi
+ if test -z "$kde_datadir"; then
+ kde_datadir='\${datadir}/apps'
+ fi
+ if test -z "$kde_locale"; then
+ kde_locale='\${datadir}/locale'
+ fi
+ if test -z "$kde_cgidir"; then
+ kde_cgidir='\${exec_prefix}/cgi-bin'
+ fi
+ if test -z "$kde_confdir"; then
+ kde_confdir='\${datadir}/config'
+ fi
+ if test -z "$kde_kcfgdir"; then
+ kde_kcfgdir='\${datadir}/config.kcfg'
+ fi
+ if test -z "$kde_mimedir"; then
+ kde_mimedir='\${datadir}/mimelnk'
+ fi
+ if test -z "$kde_toolbardir"; then
+ kde_toolbardir='\${datadir}/toolbar'
+ fi
+ if test -z "$kde_wallpaperdir"; then
+ kde_wallpaperdir='\${datadir}/wallpapers'
+ fi
+ if test -z "$kde_templatesdir"; then
+ kde_templatesdir='\${datadir}/templates'
+ fi
+ if test -z "$kde_bindir"; then
+ kde_bindir='\${exec_prefix}/bin'
+ fi
+ if test -z "$kde_servicesdir"; then
+ kde_servicesdir='\${datadir}/services'
+ fi
+ if test -z "$kde_servicetypesdir"; then
+ kde_servicetypesdir='\${datadir}/servicetypes'
+ fi
+ if test -z "$kde_moduledir"; then
+ if test "$kde_qtver" = "2"; then
+ kde_moduledir='\${libdir}/kde2'
+ else
+ kde_moduledir='\${libdir}/kde3'
+ fi
+ fi
+ if test -z "$kde_styledir"; then
+ kde_styledir='\${libdir}/kde3/plugins/styles'
+ fi
+ if test -z "$kde_widgetdir"; then
+ kde_widgetdir='\${libdir}/kde3/plugins/designer'
+ fi
+ if test -z "$xdg_appsdir"; then
+ xdg_appsdir='\${datadir}/applications/kde'
+ fi
+ if test -z "$xdg_menudir"; then
+ xdg_menudir='\${sysconfdir}/xdg/menus'
+ fi
+ if test -z "$xdg_directorydir"; then
+ xdg_directorydir='\${datadir}/desktop-directories'
+ fi
+
+ KDE_SET_PATHS(defaults)
+
+else
+
+ if test $kde_qtver = 1; then
+ AC_MSG_RESULT([compiling])
+ KDE_1_CHECK_PATHS
+ else
+ AC_MSG_ERROR([path checking not yet supported for KDE 2])
+ fi
+
+fi
+])
+
+AC_DEFUN([KDE_CHECK_PATHS_FOR_COMPLETENESS],
+[ if test -z "$kde_htmldir" || test -z "$kde_appsdir" ||
+ test -z "$kde_icondir" || test -z "$kde_sounddir" ||
+ test -z "$kde_datadir" || test -z "$kde_locale" ||
+ test -z "$kde_cgidir" || test -z "$kde_confdir" ||
+ test -z "$kde_kcfgdir" ||
+ test -z "$kde_mimedir" || test -z "$kde_toolbardir" ||
+ test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" ||
+ test -z "$kde_bindir" || test -z "$kde_servicesdir" ||
+ test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" ||
+ test -z "$kde_styledir" || test -z "kde_widgetdir" ||
+ test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_directorydir" ||
+ test "x$kde_have_all_paths" != "xyes"; then
+ kde_have_all_paths=no
+ fi
+])
+
+AC_DEFUN([KDE_MISSING_PROG_ERROR],
+[
+ AC_MSG_ERROR([The important program $1 was not found!
+Please check whether you installed KDE correctly.
+])
+])
+
+AC_DEFUN([KDE_MISSING_ARTS_ERROR],
+[
+ AC_MSG_ERROR([The important program $1 was not found!
+Please check whether you installed aRts correctly or use
+--without-arts to compile without aRts support (this will remove functionality).
+])
+])
+
+AC_DEFUN([KDE_SET_DEFAULT_BINDIRS],
+[
+ kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin"
+ test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs"
+ if test -n "$KDEDIRS"; then
+ kde_save_IFS=$IFS
+ IFS=:
+ for dir in $KDEDIRS; do
+ kde_default_bindirs="$dir/bin $kde_default_bindirs "
+ done
+ IFS=$kde_save_IFS
+ fi
+])
+
+AC_DEFUN([KDE_SUBST_PROGRAMS],
+[
+ AC_ARG_WITH(arts,
+ AC_HELP_STRING([--without-arts],[build without aRts [default=no]]),
+ [build_arts=$withval],
+ [build_arts=yes]
+ )
+ AM_CONDITIONAL(include_ARTS, test "$build_arts" '!=' "no")
+ if test "$build_arts" = "no"; then
+ AC_DEFINE(WITHOUT_ARTS, 1, [Defined if compiling without arts])
+ fi
+
+ KDE_SET_DEFAULT_BINDIRS
+ kde_default_bindirs="$exec_prefix/bin $prefix/bin $kde_libs_prefix/bin $kde_default_bindirs"
+ KDE_FIND_PATH(dcopidl, DCOPIDL, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl)])
+ KDE_FIND_PATH(dcopidl2cpp, DCOPIDL2CPP, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl2cpp)])
+ if test "$build_arts" '!=' "no"; then
+ KDE_FIND_PATH(mcopidl, MCOPIDL, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(mcopidl)])
+ KDE_FIND_PATH(artsc-config, ARTSCCONFIG, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(artsc-config)])
+ fi
+ KDE_FIND_PATH(meinproc, MEINPROC, [$kde_default_bindirs])
+
+ kde32ornewer=1
+ kde33ornewer=1
+ if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then
+ kde32ornewer=
+ kde33ornewer=
+ else
+ if test "$kde_qtver" = "3"; then
+ if test "$kde_qtsubver" -le 1; then
+ kde32ornewer=
+ fi
+ if test "$kde_qtsubver" -le 2; then
+ kde33ornewer=
+ fi
+ if test "$KDECONFIG" != "compiled"; then
+ if test `$KDECONFIG --version | grep KDE | sed 's/KDE: \(...\).*/\1/'` = 3.2; then
+ kde33ornewer=
+ fi
+ fi
+ fi
+ fi
+
+ if test -n "$kde32ornewer"; then
+ KDE_FIND_PATH(kconfig_compiler, KCONFIG_COMPILER, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kconfig_compiler)])
+ KDE_FIND_PATH(dcopidlng, DCOPIDLNG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidlng)])
+ fi
+ if test -n "$kde33ornewer"; then
+ KDE_FIND_PATH(makekdewidgets, MAKEKDEWIDGETS, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(makekdewidgets)])
+ AC_SUBST(MAKEKDEWIDGETS)
+ fi
+ KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin], [XMLLINT=""])
+
+ if test -n "$MEINPROC" -a "$MEINPROC" != "compiled"; then
+ kde_sharedirs="/usr/share/kde /usr/local/share /usr/share /opt/kde3/share /opt/kde/share $prefix/share"
+ test -n "$KDEDIR" && kde_sharedirs="$KDEDIR/share $kde_sharedirs"
+ AC_FIND_FILE(apps/ksgmltools2/customization/kde-chunk.xsl, $kde_sharedirs, KDE_XSL_STYLESHEET)
+ if test "$KDE_XSL_STYLESHEET" = "NO"; then
+ KDE_XSL_STYLESHEET=""
+ else
+ KDE_XSL_STYLESHEET="$KDE_XSL_STYLESHEET/apps/ksgmltools2/customization/kde-chunk.xsl"
+ fi
+ fi
+
+ DCOP_DEPENDENCIES='$(DCOPIDL)'
+ if test -n "$kde32ornewer"; then
+ KCFG_DEPENDENCIES='$(KCONFIG_COMPILER)'
+ DCOP_DEPENDENCIES='$(DCOPIDL) $(DCOPIDLNG)'
+ AC_SUBST(KCONFIG_COMPILER)
+ AC_SUBST(KCFG_DEPENDENCIES)
+ AC_SUBST(DCOPIDLNG)
+ fi
+ AC_SUBST(DCOPIDL)
+ AC_SUBST(DCOPIDL2CPP)
+ AC_SUBST(DCOP_DEPENDENCIES)
+ AC_SUBST(MCOPIDL)
+ AC_SUBST(ARTSCCONFIG)
+ AC_SUBST(MEINPROC)
+ AC_SUBST(KDE_XSL_STYLESHEET)
+ AC_SUBST(XMLLINT)
+])dnl
+
+AC_DEFUN([AC_CREATE_KFSSTND],
+[
+AC_REQUIRE([AC_CHECK_RPATH])
+
+AC_MSG_CHECKING([for KDE paths])
+kde_result=""
+kde_cached_paths=yes
+AC_CACHE_VAL(kde_cv_all_paths,
+[
+ KDE_SET_DEFAULT_PATHS($1)
+ kde_cached_paths=no
+])
+eval "$kde_cv_all_paths"
+KDE_CHECK_PATHS_FOR_COMPLETENESS
+if test "$kde_have_all_paths" = "no" && test "$kde_cached_paths" = "yes"; then
+ # wrong values were cached, may be, we can set better ones
+ kde_result=
+ kde_htmldir= kde_appsdir= kde_icondir= kde_sounddir=
+ kde_datadir= kde_locale= kde_cgidir= kde_confdir= kde_kcfgdir=
+ kde_mimedir= kde_toolbardir= kde_wallpaperdir= kde_templatesdir=
+ kde_bindir= kde_servicesdir= kde_servicetypesdir= kde_moduledir=
+ kde_have_all_paths=
+ kde_styledir=
+ kde_widgetdir=
+ xdg_appsdir = xdg_menudir= xdg_directorydir=
+ KDE_SET_DEFAULT_PATHS($1)
+ eval "$kde_cv_all_paths"
+ KDE_CHECK_PATHS_FOR_COMPLETENESS
+ kde_result="$kde_result (cache overridden)"
+fi
+if test "$kde_have_all_paths" = "no"; then
+ AC_MSG_ERROR([configure could not run a little KDE program to test the environment.
+Since it had compiled and linked before, it must be a strange problem on your system.
+Look at config.log for details. If you are not able to fix this, look at
+http://www.kde.org/faq/installation.html or any www.kde.org mirror.
+(If you're using an egcs version on Linux, you may update binutils!)
+])
+else
+ rm -f conftest*
+ AC_MSG_RESULT($kde_result)
+fi
+
+bindir=$kde_bindir
+
+KDE_SUBST_PROGRAMS
+
+])
+
+AC_DEFUN([AC_SUBST_KFSSTND],
+[
+AC_SUBST(kde_htmldir)
+AC_SUBST(kde_appsdir)
+AC_SUBST(kde_icondir)
+AC_SUBST(kde_sounddir)
+AC_SUBST(kde_datadir)
+AC_SUBST(kde_locale)
+AC_SUBST(kde_confdir)
+AC_SUBST(kde_kcfgdir)
+AC_SUBST(kde_mimedir)
+AC_SUBST(kde_wallpaperdir)
+AC_SUBST(kde_bindir)
+dnl X Desktop Group standards
+AC_SUBST(xdg_appsdir)
+AC_SUBST(xdg_menudir)
+AC_SUBST(xdg_directorydir)
+dnl for KDE 2
+AC_SUBST(kde_templatesdir)
+AC_SUBST(kde_servicesdir)
+AC_SUBST(kde_servicetypesdir)
+AC_SUBST(kde_moduledir)
+AC_SUBST(kdeinitdir, '$(kde_moduledir)')
+AC_SUBST(kde_styledir)
+AC_SUBST(kde_widgetdir)
+if test "$kde_qtver" = 1; then
+ kde_minidir="$kde_icondir/mini"
+else
+# for KDE 1 - this breaks KDE2 apps using minidir, but
+# that's the plan ;-/
+ kde_minidir="/dev/null"
+fi
+dnl AC_SUBST(kde_minidir)
+dnl AC_SUBST(kde_cgidir)
+dnl AC_SUBST(kde_toolbardir)
+])
+
+AC_DEFUN([KDE_MISC_TESTS],
+[
+ dnl Checks for libraries.
+ AC_CHECK_LIB(util, main, [LIBUTIL="-lutil"]) dnl for *BSD
+ AC_SUBST(LIBUTIL)
+ AC_CHECK_LIB(compat, main, [LIBCOMPAT="-lcompat"]) dnl for *BSD
+ AC_SUBST(LIBCOMPAT)
+ kde_have_crypt=
+ AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"; kde_have_crypt=yes],
+ AC_CHECK_LIB(c, crypt, [kde_have_crypt=yes], [
+ AC_MSG_WARN([you have no crypt in either libcrypt or libc.
+You should install libcrypt from another source or configure with PAM
+support])
+ kde_have_crypt=no
+ ]))
+ AC_SUBST(LIBCRYPT)
+ if test $kde_have_crypt = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_CRYPT, 1, [Defines if your system has the crypt function])
+ fi
+ AC_CHECK_SOCKLEN_T
+ AC_CHECK_LIB(dnet, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"])
+ if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+ AC_CHECK_LIB(dnet_stub, dnet_ntoa,
+ [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"])
+ fi
+ AC_CHECK_FUNC(inet_ntoa)
+ if test $ac_cv_func_inet_ntoa = no; then
+ AC_CHECK_LIB(nsl, inet_ntoa, X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl")
+ fi
+ AC_CHECK_FUNC(connect)
+ if test $ac_cv_func_connect = no; then
+ AC_CHECK_LIB(socket, connect, X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS", ,
+ $X_EXTRA_LIBS)
+ fi
+
+ AC_CHECK_FUNC(remove)
+ if test $ac_cv_func_remove = no; then
+ AC_CHECK_LIB(posix, remove, X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix")
+ fi
+
+ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+ AC_CHECK_FUNC(shmat, ,
+ AC_CHECK_LIB(ipc, shmat, X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"))
+
+ # more headers that need to be explicitly included on darwin
+ AC_CHECK_HEADERS(sys/types.h stdint.h)
+
+ # sys/bitypes.h is needed for uint32_t and friends on Tru64
+ AC_CHECK_HEADERS(sys/bitypes.h)
+
+ # darwin requires a poll emulation library
+ AC_CHECK_LIB(poll, poll, LIB_POLL="-lpoll")
+
+ # for some image handling on Mac OS X
+ AC_CHECK_HEADERS(Carbon/Carbon.h)
+
+ # CoreAudio framework
+ AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [
+ AC_DEFINE(HAVE_COREAUDIO, 1, [Define if you have the CoreAudio API])
+ FRAMEWORK_COREAUDIO="-Wl,-framework,CoreAudio"
+ ])
+
+ AC_CHECK_RES_INIT
+ AC_SUBST(LIB_POLL)
+ AC_SUBST(FRAMEWORK_COREAUDIO)
+ LIBSOCKET="$X_EXTRA_LIBS"
+ AC_SUBST(LIBSOCKET)
+ AC_SUBST(X_EXTRA_LIBS)
+ AC_CHECK_LIB(ucb, killpg, [LIBUCB="-lucb"]) dnl for Solaris2.4
+ AC_SUBST(LIBUCB)
+
+ case $host in dnl this *is* LynxOS specific
+ *-*-lynxos* )
+ AC_MSG_CHECKING([LynxOS header file wrappers])
+ [CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"]
+ AC_MSG_RESULT(disabled)
+ AC_CHECK_LIB(bsd, gethostbyname, [LIBSOCKET="-lbsd"]) dnl for LynxOS
+ ;;
+ esac
+
+ KDE_CHECK_TYPES
+ KDE_CHECK_LIBDL
+ KDE_CHECK_STRLCPY
+ KDE_CHECK_PIE_SUPPORT
+
+# darwin needs this to initialize the environment
+AC_CHECK_HEADERS(crt_externs.h)
+AC_CHECK_FUNC(_NSGetEnviron, [AC_DEFINE(HAVE_NSGETENVIRON, 1, [Define if your system needs _NSGetEnviron to set up the environment])])
+
+AH_VERBATIM(_DARWIN_ENVIRON,
+[
+#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H)
+# include <sys/time.h>
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron())
+#endif
+])
+
+AH_VERBATIM(_AIX_STRINGS_H_BZERO,
+[
+/*
+ * AIX defines FD_SET in terms of bzero, but fails to include <strings.h>
+ * that defines bzero.
+ */
+
+#if defined(_AIX)
+#include <strings.h>
+#endif
+])
+
+AC_CHECK_FUNCS([vsnprintf snprintf])
+
+AH_VERBATIM(_TRU64,[
+/*
+ * On HP-UX, the declaration of vsnprintf() is needed every time !
+ */
+
+#if !defined(HAVE_VSNPRINTF) || defined(hpux)
+#if __STDC__
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+#ifdef __cplusplus
+extern "C"
+#endif
+int vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
+#ifdef __cplusplus
+extern "C"
+#endif
+int snprintf(char *str, size_t n, char const *fmt, ...);
+#endif
+])
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Find the header files and libraries for X-Windows. Extended the
+dnl macro AC_PATH_X
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([K_PATH_X],
+[
+AC_REQUIRE([KDE_MISC_TESTS])dnl
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+AC_ARG_ENABLE(
+ embedded,
+ AC_HELP_STRING([--enable-embedded],[link to Qt-embedded, don't use X]),
+ kde_use_qt_emb=$enableval,
+ kde_use_qt_emb=no
+)
+
+AC_ARG_ENABLE(
+ qtopia,
+ AC_HELP_STRING([--enable-qtopia],[link to Qt-embedded, link to the Qtopia Environment]),
+ kde_use_qt_emb_palm=$enableval,
+ kde_use_qt_emb_palm=no
+)
+
+AC_ARG_ENABLE(
+ mac,
+ AC_HELP_STRING([--enable-mac],[link to Qt/Mac (don't use X)]),
+ kde_use_qt_mac=$enableval,
+ kde_use_qt_mac=no
+)
+
+# used to disable x11-specific stuff on special platforms
+AM_CONDITIONAL(include_x11, test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no")
+
+if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then
+
+AC_MSG_CHECKING(for X)
+
+AC_CACHE_VAL(kde_cv_have_x,
+[# One or both of the vars are not set, and there is no cached value.
+if test "{$x_includes+set}" = set || test "$x_includes" = NONE; then
+ kde_x_includes=NO
+else
+ kde_x_includes=$x_includes
+fi
+if test "{$x_libraries+set}" = set || test "$x_libraries" = NONE; then
+ kde_x_libraries=NO
+else
+ kde_x_libraries=$x_libraries
+fi
+
+# below we use the standard autoconf calls
+ac_x_libraries=$kde_x_libraries
+ac_x_includes=$kde_x_includes
+
+KDE_PATH_X_DIRECT
+dnl AC_PATH_X_XMKMF picks /usr/lib as the path for the X libraries.
+dnl Unfortunately, if compiling with the N32 ABI, this is not the correct
+dnl location. The correct location is /usr/lib32 or an undefined value
+dnl (the linker is smart enough to pick the correct default library).
+dnl Things work just fine if you use just AC_PATH_X_DIRECT.
+dnl Solaris has a similar problem. AC_PATH_X_XMKMF forces x_includes to
+dnl /usr/openwin/include, which doesn't work. /usr/include does work, so
+dnl x_includes should be left alone.
+case "$host" in
+mips-sgi-irix6*)
+ ;;
+*-*-solaris*)
+ ;;
+*)
+ _AC_PATH_X_XMKMF
+ if test -z "$ac_x_includes"; then
+ ac_x_includes="."
+ fi
+ if test -z "$ac_x_libraries"; then
+ ac_x_libraries="/usr/lib${kdelibsuff}"
+ fi
+esac
+#from now on we use our own again
+
+# when the user already gave --x-includes, we ignore
+# what the standard autoconf macros told us.
+if test "$kde_x_includes" = NO; then
+ kde_x_includes=$ac_x_includes
+fi
+
+# for --x-libraries too
+if test "$kde_x_libraries" = NO; then
+ kde_x_libraries=$ac_x_libraries
+fi
+
+if test "$kde_x_includes" = NO; then
+ AC_MSG_ERROR([Can't find X includes. Please check your installation and add the correct paths!])
+fi
+
+if test "$kde_x_libraries" = NO; then
+ AC_MSG_ERROR([Can't find X libraries. Please check your installation and add the correct paths!])
+fi
+
+# Record where we found X for the cache.
+kde_cv_have_x="have_x=yes \
+ kde_x_includes=$kde_x_includes kde_x_libraries=$kde_x_libraries"
+])dnl
+
+eval "$kde_cv_have_x"
+
+if test "$have_x" != yes; then
+ AC_MSG_RESULT($have_x)
+ no_x=yes
+else
+ AC_MSG_RESULT([libraries $kde_x_libraries, headers $kde_x_includes])
+fi
+
+if test -z "$kde_x_includes" || test "x$kde_x_includes" = xNONE; then
+ X_INCLUDES=""
+ x_includes="."; dnl better than nothing :-
+ else
+ x_includes=$kde_x_includes
+ X_INCLUDES="-I$x_includes"
+fi
+
+if test -z "$kde_x_libraries" || test "x$kde_x_libraries" = xNONE || test "$kde_x_libraries" = "/usr/lib"; then
+ X_LDFLAGS=""
+ x_libraries="/usr/lib"; dnl better than nothing :-
+ else
+ x_libraries=$kde_x_libraries
+ X_LDFLAGS="-L$x_libraries"
+fi
+all_includes="$X_INCLUDES"
+all_libraries="$X_LDFLAGS $LDFLAGS_AS_NEEDED $LDFLAGS_NEW_DTAGS"
+
+# Check for libraries that X11R6 Xt/Xaw programs need.
+ac_save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $X_LDFLAGS"
+# SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+# check for ICE first), but we must link in the order -lSM -lICE or
+# we get undefined symbols. So assume we have SM if we have ICE.
+# These have to be linked with before -lX11, unlike the other
+# libraries we check for below, so use a different variable.
+# --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+AC_CHECK_LIB(ICE, IceConnectionNumber,
+ [LIBSM="-lSM -lICE"], , $X_EXTRA_LIBS)
+LDFLAGS="$ac_save_LDFLAGS"
+
+LIB_X11='-lX11 $(LIBSOCKET)'
+
+AC_MSG_CHECKING(for libXext)
+AC_CACHE_VAL(kde_cv_have_libXext,
+[
+kde_ldflags_safe="$LDFLAGS"
+kde_libs_safe="$LIBS"
+
+LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS"
+LIBS="-lXext -lX11 $LIBSOCKET"
+
+AC_TRY_LINK([
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+],
+[
+printf("hello Xext\n");
+],
+kde_cv_have_libXext=yes,
+kde_cv_have_libXext=no
+)
+
+LDFLAGS=$kde_ldflags_safe
+LIBS=$kde_libs_safe
+])
+
+AC_MSG_RESULT($kde_cv_have_libXext)
+
+if test "$kde_cv_have_libXext" = "no"; then
+ AC_MSG_ERROR([We need a working libXext to proceed. Since configure
+can't find it itself, we stop here assuming that make wouldn't find
+them either.])
+fi
+
+LIB_XEXT="-lXext"
+QTE_NORTTI=""
+
+elif test "$kde_use_qt_emb" = "yes"; then
+ dnl We're using QT Embedded
+ CPPFLAGS=-DQWS
+ CXXFLAGS="$CXXFLAGS -fno-rtti"
+ QTE_NORTTI="-fno-rtti -DQWS"
+ X_PRE_LIBS=""
+ LIB_X11=""
+ LIB_XEXT=""
+ LIB_XRENDER=""
+ LIBSM=""
+ X_INCLUDES=""
+ X_LDFLAGS=""
+ x_includes=""
+ x_libraries=""
+elif test "$kde_use_qt_mac" = "yes"; then
+ dnl We're using QT/Mac (I use QT_MAC so that qglobal.h doesn't *have* to
+ dnl be included to get the information) --Sam
+ CXXFLAGS="$CXXFLAGS -DQT_MAC -no-cpp-precomp"
+ CFLAGS="$CFLAGS -DQT_MAC -no-cpp-precomp"
+ X_PRE_LIBS=""
+ LIB_X11=""
+ LIB_XEXT=""
+ LIB_XRENDER=""
+ LIBSM=""
+ X_INCLUDES=""
+ X_LDFLAGS=""
+ x_includes=""
+ x_libraries=""
+fi
+AC_SUBST(X_PRE_LIBS)
+AC_SUBST(LIB_X11)
+AC_SUBST(LIB_XRENDER)
+AC_SUBST(LIBSM)
+AC_SUBST(X_INCLUDES)
+AC_SUBST(X_LDFLAGS)
+AC_SUBST(x_includes)
+AC_SUBST(x_libraries)
+AC_SUBST(QTE_NORTTI)
+AC_SUBST(LIB_XEXT)
+
+])
+
+AC_DEFUN([KDE_PRINT_QT_PROGRAM],
+[
+AC_REQUIRE([KDE_USE_QT])
+cat > conftest.$ac_ext <<EOF
+#include "confdefs.h"
+#include <qglobal.h>
+#include <qapplication.h>
+EOF
+if test "$kde_qtver" = "2"; then
+cat >> conftest.$ac_ext <<EOF
+#include <qevent.h>
+#include <qstring.h>
+#include <qstyle.h>
+EOF
+
+if test $kde_qtsubver -gt 0; then
+cat >> conftest.$ac_ext <<EOF
+#if QT_VERSION < 210
+#error 1
+#endif
+EOF
+fi
+fi
+
+if test "$kde_qtver" = "3"; then
+cat >> conftest.$ac_ext <<EOF
+#include <qcursor.h>
+#include <qstylefactory.h>
+#include <private/qucomextra_p.h>
+EOF
+fi
+
+echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext
+cat >> conftest.$ac_ext <<EOF
+#error 1
+#endif
+
+int main() {
+EOF
+if test "$kde_qtver" = "2"; then
+cat >> conftest.$ac_ext <<EOF
+ QStringList *t = new QStringList();
+ Q_UNUSED(t);
+EOF
+if test $kde_qtsubver -gt 0; then
+cat >> conftest.$ac_ext <<EOF
+ QString s;
+ s.setLatin1("Elvis is alive", 14);
+EOF
+fi
+fi
+if test "$kde_qtver" = "3"; then
+cat >> conftest.$ac_ext <<EOF
+ (void)QStyleFactory::create(QString::null);
+ QCursor c(Qt::WhatsThisCursor);
+EOF
+fi
+cat >> conftest.$ac_ext <<EOF
+ return 0;
+}
+EOF
+])
+
+AC_DEFUN([KDE_USE_QT],
+[
+if test -z "$1"; then
+ # Current default Qt version: 3.3
+ kde_qtver=3
+ kde_qtsubver=3
+else
+ kde_qtsubver=`echo "$1" | sed -e 's#[0-9][0-9]*\.\([0-9][0-9]*\).*#\1#'`
+ # following is the check if subversion isnt found in passed argument
+ if test "$kde_qtsubver" = "$1"; then
+ kde_qtsubver=1
+ fi
+ kde_qtver=`echo "$1" | sed -e 's#^\([0-9][0-9]*\)\..*#\1#'`
+ if test "$kde_qtver" = "1"; then
+ kde_qtsubver=42
+ fi
+fi
+
+if test -z "$2"; then
+ if test "$kde_qtver" = "2"; then
+ if test $kde_qtsubver -gt 0; then
+ kde_qt_minversion=">= Qt 2.2.2"
+ else
+ kde_qt_minversion=">= Qt 2.0.2"
+ fi
+ fi
+ if test "$kde_qtver" = "3"; then
+ if test $kde_qtsubver -gt 0; then
+ if test $kde_qtsubver -gt 1; then
+ if test $kde_qtsubver -gt 2; then
+ kde_qt_minversion=">= Qt 3.3 and < 4.0"
+ else
+ kde_qt_minversion=">= Qt 3.2 and < 4.0"
+ fi
+ else
+ kde_qt_minversion=">= Qt 3.1 (20021021) and < 4.0"
+ fi
+ else
+ kde_qt_minversion=">= Qt 3.0 and < 4.0"
+ fi
+ fi
+ if test "$kde_qtver" = "1"; then
+ kde_qt_minversion=">= 1.42 and < 2.0"
+ fi
+else
+ kde_qt_minversion="$2"
+fi
+
+if test -z "$3"; then
+ if test $kde_qtver = 3; then
+ if test $kde_qtsubver -gt 0; then
+ kde_qt_verstring="QT_VERSION >= 0x03@VER@00 && QT_VERSION < 0x040000"
+ qtsubver=`echo "00$kde_qtsubver" | sed -e 's,.*\(..\)$,\1,'`
+ kde_qt_verstring=`echo $kde_qt_verstring | sed -e "s,@VER@,$qtsubver,"`
+ else
+ kde_qt_verstring="QT_VERSION >= 300 && QT_VERSION < 0x040000"
+ fi
+ fi
+ if test $kde_qtver = 2; then
+ if test $kde_qtsubver -gt 0; then
+ kde_qt_verstring="QT_VERSION >= 222"
+ else
+ kde_qt_verstring="QT_VERSION >= 200"
+ fi
+ fi
+ if test $kde_qtver = 1; then
+ kde_qt_verstring="QT_VERSION >= 142 && QT_VERSION < 200"
+ fi
+else
+ kde_qt_verstring="$3"
+fi
+
+if test $kde_qtver = 4; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt4 /usr/lib/qt /usr/share/qt4"
+fi
+if test $kde_qtver = 3; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt3 /usr/lib/qt /usr/share/qt3"
+fi
+if test $kde_qtver = 2; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt2 /usr/lib/qt"
+fi
+if test $kde_qtver = 1; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt"
+fi
+])
+
+AC_DEFUN([KDE_CHECK_QT_DIRECT],
+[
+AC_REQUIRE([KDE_USE_QT])
+AC_MSG_CHECKING([if Qt compiles without flags])
+AC_CACHE_VAL(kde_cv_qt_direct,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ac_LD_LIBRARY_PATH_safe=$LD_LIBRARY_PATH
+ac_LIBRARY_PATH="$LIBRARY_PATH"
+ac_cxxflags_safe="$CXXFLAGS"
+ac_ldflags_safe="$LDFLAGS"
+ac_libs_safe="$LIBS"
+
+CXXFLAGS="$CXXFLAGS -I$qt_includes"
+LDFLAGS="$LDFLAGS $X_LDFLAGS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$LIBQT -lXext -lX11 $LIBSOCKET"
+else
+LIBS="$LIBQT $LIBSOCKET"
+fi
+LD_LIBRARY_PATH=
+export LD_LIBRARY_PATH
+LIBRARY_PATH=
+export LIBRARY_PATH
+
+KDE_PRINT_QT_PROGRAM
+
+if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ kde_cv_qt_direct="yes"
+else
+ kde_cv_qt_direct="no"
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&AC_FD_CC
+fi
+
+rm -f conftest*
+CXXFLAGS="$ac_cxxflags_safe"
+LDFLAGS="$ac_ldflags_safe"
+LIBS="$ac_libs_safe"
+
+LD_LIBRARY_PATH="$ac_LD_LIBRARY_PATH_safe"
+export LD_LIBRARY_PATH
+LIBRARY_PATH="$ac_LIBRARY_PATH"
+export LIBRARY_PATH
+AC_LANG_RESTORE
+])
+
+if test "$kde_cv_qt_direct" = "yes"; then
+ AC_MSG_RESULT(yes)
+ $1
+else
+ AC_MSG_RESULT(no)
+ $2
+fi
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the Qt headers and libraries.
+dnl $(QT_LDFLAGS) will be -Lqtliblocation (if needed)
+dnl and $(QT_INCLUDES) will be -Iqthdrlocation (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_PATH_QT_1_3],
+[
+AC_REQUIRE([K_PATH_X])
+AC_REQUIRE([KDE_USE_QT])
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+dnl ------------------------------------------------------------------------
+dnl Add configure flag to enable linking to MT version of Qt library.
+dnl ------------------------------------------------------------------------
+
+AC_ARG_ENABLE(
+ mt,
+ AC_HELP_STRING([--disable-mt],[link to non-threaded Qt (deprecated)]),
+ kde_use_qt_mt=$enableval,
+ [
+ if test $kde_qtver = 3; then
+ kde_use_qt_mt=yes
+ else
+ kde_use_qt_mt=no
+ fi
+ ]
+)
+
+USING_QT_MT=""
+
+dnl ------------------------------------------------------------------------
+dnl If we not get --disable-qt-mt then adjust some vars for the host.
+dnl ------------------------------------------------------------------------
+
+KDE_MT_LDFLAGS=
+KDE_MT_LIBS=
+if test "x$kde_use_qt_mt" = "xyes"; then
+ KDE_CHECK_THREADING
+ if test "x$kde_use_threading" = "xyes"; then
+ CPPFLAGS="$USE_THREADS -DQT_THREAD_SUPPORT $CPPFLAGS"
+ KDE_MT_LDFLAGS="$USE_THREADS"
+ KDE_MT_LIBS="$LIBPTHREAD"
+ else
+ kde_use_qt_mt=no
+ fi
+fi
+AC_SUBST(KDE_MT_LDFLAGS)
+AC_SUBST(KDE_MT_LIBS)
+
+kde_qt_was_given=yes
+
+dnl ------------------------------------------------------------------------
+dnl If we haven't been told how to link to Qt, we work it out for ourselves.
+dnl ------------------------------------------------------------------------
+if test -z "$LIBQT_GLOB"; then
+ if test "x$kde_use_qt_emb" = "xyes"; then
+ LIBQT_GLOB="libqte.*"
+ else
+ LIBQT_GLOB="libqt.*"
+ fi
+fi
+
+dnl ------------------------------------------------------------
+dnl If we got --enable-embedded then adjust the Qt library name.
+dnl ------------------------------------------------------------
+if test "x$kde_use_qt_emb" = "xyes"; then
+ qtlib="qte"
+else
+ qtlib="qt"
+fi
+
+kde_int_qt="-l$qtlib"
+
+if test -z "$LIBQPE"; then
+dnl ------------------------------------------------------------
+dnl If we got --enable-palmtop then add -lqpe to the link line
+dnl ------------------------------------------------------------
+ if test "x$kde_use_qt_emb" = "xyes"; then
+ if test "x$kde_use_qt_emb_palm" = "xyes"; then
+ LIB_QPE="-lqpe"
+ else
+ LIB_QPE=""
+ fi
+ else
+ LIB_QPE=""
+ fi
+fi
+
+dnl ------------------------------------------------------------------------
+dnl If we got --enable-qt-mt then adjust the Qt library name for the host.
+dnl ------------------------------------------------------------------------
+
+if test "x$kde_use_qt_mt" = "xyes"; then
+ LIBQT="-l$qtlib-mt"
+ kde_int_qt="-l$qtlib-mt"
+ LIBQT_GLOB="lib$qtlib-mt.*"
+ USING_QT_MT="using -mt"
+else
+ LIBQT="-l$qtlib"
+fi
+
+if test $kde_qtver != 1; then
+
+ AC_REQUIRE([AC_FIND_PNG])
+ AC_REQUIRE([AC_FIND_JPEG])
+ LIBQT="$LIBQT $LIBPNG $LIBJPEG"
+fi
+
+if test $kde_qtver = 3; then
+ AC_REQUIRE([KDE_CHECK_LIBDL])
+ LIBQT="$LIBQT $LIBDL"
+fi
+
+AC_MSG_CHECKING([for Qt])
+
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBQT="$LIBQT $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET"
+fi
+ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO
+qt_libraries=""
+qt_includes=""
+AC_ARG_WITH(qt-dir,
+ AC_HELP_STRING([--with-qt-dir=DIR],[where the root of Qt is installed ]),
+ [ ac_qt_includes="$withval"/include
+ ac_qt_libraries="$withval"/lib${kdelibsuff}
+ ac_qt_bindir="$withval"/bin
+ ])
+
+AC_ARG_WITH(qt-includes,
+ AC_HELP_STRING([--with-qt-includes=DIR],[where the Qt includes are. ]),
+ [
+ ac_qt_includes="$withval"
+ ])
+
+kde_qt_libs_given=no
+
+AC_ARG_WITH(qt-libraries,
+ AC_HELP_STRING([--with-qt-libraries=DIR],[where the Qt library is installed.]),
+ [ ac_qt_libraries="$withval"
+ kde_qt_libs_given=yes
+ ])
+
+AC_CACHE_VAL(ac_cv_have_qt,
+[#try to guess Qt locations
+
+qt_incdirs=""
+for dir in $kde_qt_dirs; do
+ qt_incdirs="$qt_incdirs $dir/include $dir"
+done
+qt_incdirs="$QTINC $qt_incdirs /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/X11R6/include/qt2 /usr/include/qt3 $x_includes"
+if test ! "$ac_qt_includes" = "NO"; then
+ qt_incdirs="$ac_qt_includes $qt_incdirs"
+fi
+
+if test "$kde_qtver" != "1"; then
+ kde_qt_header=qstyle.h
+else
+ kde_qt_header=qglobal.h
+fi
+
+AC_FIND_FILE($kde_qt_header, $qt_incdirs, qt_incdir)
+ac_qt_includes="$qt_incdir"
+
+qt_libdirs=""
+for dir in $kde_qt_dirs; do
+ qt_libdirs="$qt_libdirs $dir/lib${kdelibsuff} $dir"
+done
+qt_libdirs="$QTLIB $qt_libdirs /usr/X11R6/lib /usr/lib /usr/local/qt/lib $x_libraries"
+if test ! "$ac_qt_libraries" = "NO"; then
+ qt_libdir=$ac_qt_libraries
+else
+ qt_libdirs="$ac_qt_libraries $qt_libdirs"
+ # if the Qt was given, the chance is too big that libqt.* doesn't exist
+ qt_libdir=NONE
+ for dir in $qt_libdirs; do
+ try="ls -1 $dir/${LIBQT_GLOB}"
+ if test -n "`$try 2> /dev/null`"; then qt_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi
+ done
+fi
+for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do
+ if test -e "$a"; then
+ LIBQT="$LIBQT ${kde_int_qt}_incremental"
+ break
+ fi
+done
+
+ac_qt_libraries="$qt_libdir"
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+ac_cxxflags_safe="$CXXFLAGS"
+ac_ldflags_safe="$LDFLAGS"
+ac_libs_safe="$LIBS"
+
+CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes"
+LDFLAGS="$LDFLAGS -L$qt_libdir $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS"
+LIBS="$LIBS $LIBQT $KDE_MT_LIBS"
+
+KDE_PRINT_QT_PROGRAM
+
+if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ rm -f conftest*
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&AC_FD_CC
+ ac_qt_libraries="NO"
+fi
+rm -f conftest*
+CXXFLAGS="$ac_cxxflags_safe"
+LDFLAGS="$ac_ldflags_safe"
+LIBS="$ac_libs_safe"
+
+AC_LANG_RESTORE
+if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then
+ ac_cv_have_qt="have_qt=no"
+ ac_qt_notfound=""
+ missing_qt_mt=""
+ if test "$ac_qt_includes" = NO; then
+ if test "$ac_qt_libraries" = NO; then
+ ac_qt_notfound="(headers and libraries)";
+ else
+ ac_qt_notfound="(headers)";
+ fi
+ else
+ if test "x$kde_use_qt_mt" = "xyes"; then
+ missing_qt_mt="
+Make sure that you have compiled Qt with thread support!"
+ ac_qt_notfound="(library $qtlib-mt)";
+ else
+ ac_qt_notfound="(library $qtlib)";
+ fi
+ fi
+
+ AC_MSG_ERROR([Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation!
+For more details about this problem, look at the end of config.log.$missing_qt_mt])
+else
+ have_qt="yes"
+fi
+])
+
+eval "$ac_cv_have_qt"
+
+if test "$have_qt" != yes; then
+ AC_MSG_RESULT([$have_qt]);
+else
+ ac_cv_have_qt="have_qt=yes \
+ ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries"
+ AC_MSG_RESULT([libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT])
+
+ qt_libraries="$ac_qt_libraries"
+ qt_includes="$ac_qt_includes"
+fi
+
+if test ! "$kde_qt_libs_given" = "yes" && test ! "$kde_qtver" = 3; then
+ KDE_CHECK_QT_DIRECT(qt_libraries= ,[])
+fi
+
+AC_SUBST(qt_libraries)
+AC_SUBST(qt_includes)
+
+if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then
+ QT_INCLUDES=""
+else
+ QT_INCLUDES="-I$qt_includes"
+ all_includes="$QT_INCLUDES $all_includes"
+fi
+
+if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then
+ QT_LDFLAGS=""
+else
+ QT_LDFLAGS="-L$qt_libraries"
+ all_libraries="$QT_LDFLAGS $all_libraries"
+fi
+test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS"
+
+AC_SUBST(QT_INCLUDES)
+AC_SUBST(QT_LDFLAGS)
+AC_PATH_QT_MOC_UIC
+
+KDE_CHECK_QT_JPEG
+
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)'
+else
+LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG)'
+fi
+test -z "$KDE_MT_LIBS" || LIB_QT="$LIB_QT $KDE_MT_LIBS"
+for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do
+ if test -e "$a"; then
+ LIB_QT="$LIB_QT ${kde_int_qt}_incremental"
+ break
+ fi
+done
+
+AC_SUBST(LIB_QT)
+AC_SUBST(LIB_QPE)
+
+AC_SUBST(kde_qtver)
+])
+
+AC_DEFUN([AC_PATH_QT],
+[
+AC_PATH_QT_1_3
+])
+
+AC_DEFUN([KDE_CHECK_UIC_PLUGINS],
+[
+AC_REQUIRE([AC_PATH_QT_MOC_UIC])
+
+if test x$ac_uic_supports_libpath = xyes; then
+
+AC_MSG_CHECKING([if UIC has KDE plugins available])
+AC_CACHE_VAL(kde_cv_uic_plugins,
+[
+cat > actest.ui << EOF
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>NewConnectionDialog</class>
+<widget class="QDialog">
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>testInput</cstring>
+ </property>
+ </widget>
+</widget>
+</UI>
+EOF
+
+
+
+kde_cv_uic_plugins=no
+kde_line="$UIC_PATH -L $kde_widgetdir"
+if test x$ac_uic_supports_nounload = xyes; then
+ kde_line="$kde_line -nounload"
+fi
+kde_line="$kde_line -impl actest.h actest.ui > actest.cpp"
+if AC_TRY_EVAL(kde_line); then
+ # if you're trying to debug this check and think it's incorrect,
+ # better check your installation. The check _is_ correct - your
+ # installation is not.
+ if test -f actest.cpp && grep klineedit actest.cpp > /dev/null; then
+ kde_cv_uic_plugins=yes
+ fi
+fi
+rm -f actest.ui actest.cpp
+])
+
+AC_MSG_RESULT([$kde_cv_uic_plugins])
+if test "$kde_cv_uic_plugins" != yes; then
+ AC_MSG_ERROR([
+you need to install kdelibs first.
+
+If you did install kdelibs, then the Qt version that is picked up by
+this configure is not the same version you used to compile kdelibs.
+The Qt Plugin installed by kdelibs is *ONLY* loadable if it is the
+_same Qt version_, compiled with the _same compiler_ and the same Qt
+configuration settings.
+])
+fi
+fi
+])
+
+AC_DEFUN([KDE_CHECK_FINAL],
+[
+ AC_ARG_ENABLE(final,
+ AC_HELP_STRING([--enable-final],
+ [build size optimized apps (experimental - needs lots of memory)]),
+ kde_use_final=$enableval, kde_use_final=no)
+
+ if test "x$kde_use_final" = "xyes"; then
+ KDE_USE_FINAL_TRUE=""
+ KDE_USE_FINAL_FALSE="#"
+ else
+ KDE_USE_FINAL_TRUE="#"
+ KDE_USE_FINAL_FALSE=""
+ fi
+ AC_SUBST(KDE_USE_FINAL_TRUE)
+ AC_SUBST(KDE_USE_FINAL_FALSE)
+])
+
+AC_DEFUN([KDE_CHECK_CLOSURE],
+[
+ AC_ARG_ENABLE(closure,
+ AC_HELP_STRING([--enable-closure],[delay template instantiation]),
+ kde_use_closure=$enableval, kde_use_closure=no)
+
+ KDE_NO_UNDEFINED=""
+ if test "x$kde_use_closure" = "xyes"; then
+ KDE_USE_CLOSURE_TRUE=""
+ KDE_USE_CLOSURE_FALSE="#"
+# CXXFLAGS="$CXXFLAGS $REPO"
+ else
+ KDE_USE_CLOSURE_TRUE="#"
+ KDE_USE_CLOSURE_FALSE=""
+ KDE_NO_UNDEFINED=""
+ case $host in
+ *-*-linux-gnu)
+ KDE_CHECK_COMPILER_FLAG([Wl,--no-undefined],
+ [KDE_CHECK_COMPILER_FLAG([Wl,--allow-shlib-undefined],
+ [KDE_NO_UNDEFINED="-Wl,--no-undefined -Wl,--allow-shlib-undefined"],
+ [KDE_NO_UNDEFINED=""])],
+ [KDE_NO_UNDEFINED=""])
+ ;;
+ esac
+ fi
+ AC_SUBST(KDE_USE_CLOSURE_TRUE)
+ AC_SUBST(KDE_USE_CLOSURE_FALSE)
+ AC_SUBST(KDE_NO_UNDEFINED)
+])
+
+dnl Check if the linker supports --enable-new-dtags and --as-needed
+AC_DEFUN([KDE_CHECK_NEW_LDFLAGS],
+[
+ AC_ARG_ENABLE(new_ldflags,
+ AC_HELP_STRING([--enable-new-ldflags],
+ [enable the new linker flags]),
+ kde_use_new_ldflags=$enableval,
+ kde_use_new_ldflags=no)
+
+ LDFLAGS_AS_NEEDED=""
+ LDFLAGS_NEW_DTAGS=""
+ if test "x$kde_use_new_ldflags" = "xyes"; then
+ LDFLAGS_NEW_DTAGS=""
+ KDE_CHECK_COMPILER_FLAG([Wl,--enable-new-dtags],
+ [LDFLAGS_NEW_DTAGS="-Wl,--enable-new-dtags"],)
+
+ KDE_CHECK_COMPILER_FLAG([Wl,--as-needed],
+ [LDFLAGS_AS_NEEDED="-Wl,--as-needed"],)
+ fi
+ AC_SUBST(LDFLAGS_AS_NEEDED)
+ AC_SUBST(LDFLAGS_NEW_DTAGS)
+])
+
+AC_DEFUN([KDE_CHECK_NMCHECK],
+[
+ AC_ARG_ENABLE(nmcheck,AC_HELP_STRING([--enable-nmcheck],[enable automatic namespace cleanness check]),
+ kde_use_nmcheck=$enableval, kde_use_nmcheck=no)
+
+ if test "$kde_use_nmcheck" = "yes"; then
+ KDE_USE_NMCHECK_TRUE=""
+ KDE_USE_NMCHECK_FALSE="#"
+ else
+ KDE_USE_NMCHECK_TRUE="#"
+ KDE_USE_NMCHECK_FALSE=""
+ fi
+ AC_SUBST(KDE_USE_NMCHECK_TRUE)
+ AC_SUBST(KDE_USE_NMCHECK_FALSE)
+])
+
+AC_DEFUN([KDE_EXPAND_MAKEVAR], [
+savex=$exec_prefix
+test "x$exec_prefix" = xNONE && exec_prefix=$prefix
+tmp=$$2
+while $1=`eval echo "$tmp"`; test "x$$1" != "x$tmp"; do tmp=$$1; done
+exec_prefix=$savex
+])
+
+dnl ------------------------------------------------------------------------
+dnl Now, the same with KDE
+dnl $(KDE_LDFLAGS) will be the kdeliblocation (if needed)
+dnl and $(kde_includes) will be the kdehdrlocation (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_BASE_PATH_KDE],
+[
+AC_REQUIRE([KDE_CHECK_STL])
+AC_REQUIRE([AC_PATH_QT])dnl
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+AC_CHECK_RPATH
+AC_MSG_CHECKING([for KDE])
+
+if test "${prefix}" != NONE; then
+ kde_includes=${includedir}
+ KDE_EXPAND_MAKEVAR(ac_kde_includes, includedir)
+
+ kde_libraries=${libdir}
+ KDE_EXPAND_MAKEVAR(ac_kde_libraries, libdir)
+
+else
+ ac_kde_includes=
+ ac_kde_libraries=
+ kde_libraries=""
+ kde_includes=""
+fi
+
+AC_CACHE_VAL(ac_cv_have_kde,
+[#try to guess kde locations
+
+if test "$kde_qtver" = 1; then
+ kde_check_header="ksock.h"
+ kde_check_lib="libkdecore.la"
+else
+ kde_check_header="ksharedptr.h"
+ kde_check_lib="libkio.la"
+fi
+
+if test -z "$1"; then
+
+kde_incdirs="$kde_libs_prefix/include /usr/lib/kde/include /usr/local/kde/include /usr/local/include /usr/kde/include /usr/include/kde /usr/include /opt/kde3/include /opt/kde/include $x_includes $qt_includes"
+test -n "$KDEDIR" && kde_incdirs="$KDEDIR/include $KDEDIR/include/kde $KDEDIR $kde_incdirs"
+kde_incdirs="$ac_kde_includes $kde_incdirs"
+AC_FIND_FILE($kde_check_header, $kde_incdirs, kde_incdir)
+ac_kde_includes="$kde_incdir"
+
+if test -n "$ac_kde_includes" && test ! -r "$ac_kde_includes/$kde_check_header"; then
+ AC_MSG_ERROR([
+in the prefix, you've chosen, are no KDE headers installed. This will fail.
+So, check this please and use another prefix!])
+fi
+
+kde_libdirs="$kde_libs_prefix/lib${kdelibsuff} /usr/lib/kde/lib${kdelibsuff} /usr/local/kde/lib${kdelibsuff} /usr/kde/lib${kdelibsuff} /usr/lib${kdelibsuff}/kde /usr/lib${kdelibsuff}/kde3 /usr/lib${kdelibsuff} /usr/X11R6/lib${kdelibsuff} /usr/local/lib${kdelibsuff} /opt/kde3/lib${kdelibsuff} /opt/kde/lib${kdelibsuff} /usr/X11R6/kde/lib${kdelibsuff}"
+test -n "$KDEDIR" && kde_libdirs="$KDEDIR/lib${kdelibsuff} $KDEDIR $kde_libdirs"
+kde_libdirs="$ac_kde_libraries $libdir $kde_libdirs"
+AC_FIND_FILE($kde_check_lib, $kde_libdirs, kde_libdir)
+ac_kde_libraries="$kde_libdir"
+
+kde_widgetdir=NO
+dnl this might be somewhere else
+AC_FIND_FILE("kde3/plugins/designer/kdewidgets.la", $kde_libdirs, kde_widgetdir)
+
+if test -n "$ac_kde_libraries" && test ! -r "$ac_kde_libraries/$kde_check_lib"; then
+AC_MSG_ERROR([
+in the prefix, you've chosen, are no KDE libraries installed. This will fail.
+So, check this please and use another prefix!])
+fi
+
+if test -n "$kde_widgetdir" && test ! -r "$kde_widgetdir/kde3/plugins/designer/kdewidgets.la"; then
+AC_MSG_ERROR([
+I can't find the designer plugins. These are required and should have been installed
+by kdelibs])
+fi
+
+if test -n "$kde_widgetdir"; then
+ kde_widgetdir="$kde_widgetdir/kde3/plugins/designer"
+fi
+
+
+if test "$ac_kde_includes" = NO || test "$ac_kde_libraries" = NO || test "$kde_widgetdir" = NO; then
+ ac_cv_have_kde="have_kde=no"
+else
+ ac_cv_have_kde="have_kde=yes \
+ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries"
+fi
+
+else dnl test -z $1, e.g. from kdelibs
+
+ ac_cv_have_kde="have_kde=no"
+
+fi
+])dnl
+
+eval "$ac_cv_have_kde"
+
+if test "$have_kde" != "yes"; then
+ if test "${prefix}" = NONE; then
+ ac_kde_prefix="$ac_default_prefix"
+ else
+ ac_kde_prefix="$prefix"
+ fi
+ if test "$exec_prefix" = NONE; then
+ ac_kde_exec_prefix="$ac_kde_prefix"
+ AC_MSG_RESULT([will be installed in $ac_kde_prefix])
+ else
+ ac_kde_exec_prefix="$exec_prefix"
+ AC_MSG_RESULT([will be installed in $ac_kde_prefix and $ac_kde_exec_prefix])
+ fi
+
+ kde_libraries="${libdir}"
+ kde_includes="${includedir}"
+
+else
+ ac_cv_have_kde="have_kde=yes \
+ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries"
+ AC_MSG_RESULT([libraries $ac_kde_libraries, headers $ac_kde_includes])
+
+ kde_libraries="$ac_kde_libraries"
+ kde_includes="$ac_kde_includes"
+fi
+AC_SUBST(kde_libraries)
+AC_SUBST(kde_includes)
+
+if test "$kde_includes" = "$x_includes" || test "$kde_includes" = "$qt_includes" || test "$kde_includes" = "/usr/include"; then
+ KDE_INCLUDES=""
+else
+ KDE_INCLUDES="-I$kde_includes"
+ all_includes="$KDE_INCLUDES $all_includes"
+fi
+
+KDE_DEFAULT_CXXFLAGS="-DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION"
+
+KDE_LDFLAGS="-L$kde_libraries"
+if test ! "$kde_libraries" = "$x_libraries" && test ! "$kde_libraries" = "$qt_libraries" ; then
+ all_libraries="$KDE_LDFLAGS $all_libraries"
+fi
+
+AC_SUBST(KDE_LDFLAGS)
+AC_SUBST(KDE_INCLUDES)
+
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+all_libraries="$all_libraries $USER_LDFLAGS"
+all_includes="$all_includes $USER_INCLUDES"
+AC_SUBST(all_includes)
+AC_SUBST(all_libraries)
+
+if test -z "$1"; then
+KDE_CHECK_UIC_PLUGINS
+fi
+
+ac_kde_libraries="$kde_libdir"
+
+AC_SUBST(AUTODIRS)
+
+
+])
+
+AC_DEFUN([KDE_CHECK_EXTRA_LIBS],
+[
+AC_MSG_CHECKING(for extra includes)
+AC_ARG_WITH(extra-includes,AC_HELP_STRING([--with-extra-includes=DIR],[adds non standard include paths]),
+ kde_use_extra_includes="$withval",
+ kde_use_extra_includes=NONE
+)
+kde_extra_includes=
+if test -n "$kde_use_extra_includes" && \
+ test "$kde_use_extra_includes" != "NONE"; then
+
+ ac_save_ifs=$IFS
+ IFS=':'
+ for dir in $kde_use_extra_includes; do
+ kde_extra_includes="$kde_extra_includes $dir"
+ USER_INCLUDES="$USER_INCLUDES -I$dir"
+ done
+ IFS=$ac_save_ifs
+ kde_use_extra_includes="added"
+else
+ kde_use_extra_includes="no"
+fi
+AC_SUBST(USER_INCLUDES)
+
+AC_MSG_RESULT($kde_use_extra_includes)
+
+kde_extra_libs=
+AC_MSG_CHECKING(for extra libs)
+AC_ARG_WITH(extra-libs,AC_HELP_STRING([--with-extra-libs=DIR],[adds non standard library paths]),
+ kde_use_extra_libs=$withval,
+ kde_use_extra_libs=NONE
+)
+if test -n "$kde_use_extra_libs" && \
+ test "$kde_use_extra_libs" != "NONE"; then
+
+ ac_save_ifs=$IFS
+ IFS=':'
+ for dir in $kde_use_extra_libs; do
+ kde_extra_libs="$kde_extra_libs $dir"
+ KDE_EXTRA_RPATH="$KDE_EXTRA_RPATH -R $dir"
+ USER_LDFLAGS="$USER_LDFLAGS -L$dir"
+ done
+ IFS=$ac_save_ifs
+ kde_use_extra_libs="added"
+else
+ kde_use_extra_libs="no"
+fi
+
+AC_SUBST(USER_LDFLAGS)
+
+AC_MSG_RESULT($kde_use_extra_libs)
+
+])
+
+AC_DEFUN([KDE_1_CHECK_PATH_HEADERS],
+[
+ AC_MSG_CHECKING([for KDE headers installed])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+cat > conftest.$ac_ext <<EOF
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+#include <stdio.h>
+#include "confdefs.h"
+#include <kapp.h>
+
+int main() {
+ printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data());
+ printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data());
+ printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data());
+ printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data());
+ printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data());
+ printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data());
+ printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data());
+ printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data());
+ printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data());
+ printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data());
+ printf("kde_wallpaperdir=\\"%s\\"\n",
+ KApplication::kde_wallpaperdir().data());
+ printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data());
+ printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data());
+ printf("kde_servicesdir=\\"/tmp/dummy\\"\n");
+ printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n");
+ printf("kde_moduledir=\\"/tmp/dummy\\"\n");
+ printf("kde_styledir=\\"/tmp/dummy\\"\n");
+ printf("kde_widgetdir=\\"/tmp/dummy\\"\n");
+ printf("xdg_appsdir=\\"/tmp/dummy\\"\n");
+ printf("xdg_menudir=\\"/tmp/dummy\\"\n");
+ printf("xdg_directorydir=\\"/tmp/dummy\\"\n");
+ printf("kde_kcfgdir=\\"/tmp/dummy\\"\n");
+ return 0;
+ }
+EOF
+
+ ac_save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$all_includes $CPPFLAGS"
+ if AC_TRY_EVAL(ac_compile); then
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_ERROR([your system is not able to compile a small KDE application!
+Check, if you installed the KDE header files correctly.
+For more details about this problem, look at the end of config.log.])
+ fi
+ CPPFLAGS=$ac_save_CPPFLAGS
+
+ AC_LANG_RESTORE
+])
+
+AC_DEFUN([KDE_CHECK_KDEQTADDON],
+[
+AC_MSG_CHECKING(for kde-qt-addon)
+AC_CACHE_VAL(kde_cv_have_kdeqtaddon,
+[
+ kde_ldflags_safe="$LDFLAGS"
+ kde_libs_safe="$LIBS"
+ kde_cxxflags_safe="$CXXFLAGS"
+
+ LIBS="-lkde-qt-addon $LIBQT $LIBS"
+ CXXFLAGS="$CXXFLAGS -I$prefix/include -I$prefix/include/kde $all_includes"
+ LDFLAGS="$LDFLAGS $all_libraries $USER_LDFLAGS"
+
+ AC_TRY_LINK([
+ #include <qdom.h>
+ ],
+ [
+ QDomDocument doc;
+ ],
+ kde_cv_have_kdeqtaddon=yes,
+ kde_cv_have_kdeqtaddon=no
+ )
+
+ LDFLAGS=$kde_ldflags_safe
+ LIBS=$kde_libs_safe
+ CXXFLAGS=$kde_cxxflags_safe
+])
+
+AC_MSG_RESULT($kde_cv_have_kdeqtaddon)
+
+if test "$kde_cv_have_kdeqtaddon" = "no"; then
+ AC_MSG_ERROR([Can't find libkde-qt-addon. You need to install it first.
+It is a separate package (and CVS module) named kde-qt-addon.])
+fi
+])
+
+AC_DEFUN([KDE_CREATE_LIBS_ALIASES],
+[
+ AC_REQUIRE([KDE_MISC_TESTS])
+ AC_REQUIRE([KDE_CHECK_LIBDL])
+ AC_REQUIRE([K_PATH_X])
+
+if test $kde_qtver = 3; then
+ case $host in
+ *cygwin*) lib_kded="-lkdeinit_kded" ;;
+ *) lib_kded="" ;;
+ esac
+ AC_SUBST(LIB_KDED, $lib_kded)
+ AC_SUBST(LIB_KDECORE, "-lkdecore")
+ AC_SUBST(LIB_KDEUI, "-lkdeui")
+ AC_SUBST(LIB_KIO, "-lkio")
+ AC_SUBST(LIB_KJS, "-lkjs")
+ AC_SUBST(LIB_SMB, "-lsmb")
+ AC_SUBST(LIB_KAB, "-lkab")
+ AC_SUBST(LIB_KABC, "-lkabc")
+ AC_SUBST(LIB_KHTML, "-lkhtml")
+ AC_SUBST(LIB_KSPELL, "-lkspell")
+ AC_SUBST(LIB_KPARTS, "-lkparts")
+ AC_SUBST(LIB_KDEPRINT, "-lkdeprint")
+ AC_SUBST(LIB_KUTILS, "-lkutils")
+ AC_SUBST(LIB_KDEPIM, "-lkdepim")
+ AC_SUBST(LIB_KIMPROXY, "-lkimproxy")
+ AC_SUBST(LIB_KNEWSTUFF, "-lknewstuff")
+ AC_SUBST(LIB_KDNSSD, "-lkdnssd")
+ AC_SUBST(LIB_KUNITTEST, "-lkunittest")
+# these are for backward compatibility
+ AC_SUBST(LIB_KSYCOCA, "-lkio")
+ AC_SUBST(LIB_KFILE, "-lkio")
+elif test $kde_qtver = 2; then
+ AC_SUBST(LIB_KDECORE, "-lkdecore")
+ AC_SUBST(LIB_KDEUI, "-lkdeui")
+ AC_SUBST(LIB_KIO, "-lkio")
+ AC_SUBST(LIB_KSYCOCA, "-lksycoca")
+ AC_SUBST(LIB_SMB, "-lsmb")
+ AC_SUBST(LIB_KFILE, "-lkfile")
+ AC_SUBST(LIB_KAB, "-lkab")
+ AC_SUBST(LIB_KHTML, "-lkhtml")
+ AC_SUBST(LIB_KSPELL, "-lkspell")
+ AC_SUBST(LIB_KPARTS, "-lkparts")
+ AC_SUBST(LIB_KDEPRINT, "-lkdeprint")
+else
+ AC_SUBST(LIB_KDECORE, "-lkdecore -lXext $(LIB_QT)")
+ AC_SUBST(LIB_KDEUI, "-lkdeui $(LIB_KDECORE)")
+ AC_SUBST(LIB_KFM, "-lkfm $(LIB_KDECORE)")
+ AC_SUBST(LIB_KFILE, "-lkfile $(LIB_KFM) $(LIB_KDEUI)")
+ AC_SUBST(LIB_KAB, "-lkab $(LIB_KIMGIO) $(LIB_KDECORE)")
+fi
+])
+
+AC_DEFUN([AC_PATH_KDE],
+[
+ AC_BASE_PATH_KDE
+ AC_ARG_ENABLE(path-check,AC_HELP_STRING([--disable-path-check],[don't try to find out, where to install]),
+ [
+ if test "$enableval" = "no";
+ then ac_use_path_checking="default"
+ else ac_use_path_checking=""
+ fi
+ ],
+ [
+ if test "$kde_qtver" = 1;
+ then ac_use_path_checking=""
+ else ac_use_path_checking="default"
+ fi
+ ]
+ )
+
+ AC_CREATE_KFSSTND($ac_use_path_checking)
+
+ AC_SUBST_KFSSTND
+ KDE_CREATE_LIBS_ALIASES
+])
+
+dnl KDE_CHECK_FUNC_EXT(<func>, [headers], [sample-use], [C prototype], [autoheader define], [call if found])
+AC_DEFUN([KDE_CHECK_FUNC_EXT],
+[
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(kde_cv_func_$1,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+save_CXXFLAGS="$CXXFLAGS"
+kde_safe_LIBS="$LIBS"
+LIBS="$LIBS $X_EXTRA_LIBS"
+if test "$GXX" = "yes"; then
+CXXFLAGS="$CXXFLAGS -pedantic-errors"
+fi
+AC_TRY_COMPILE([
+$2
+],
+[
+$3
+],
+kde_cv_func_$1=yes,
+kde_cv_func_$1=no)
+CXXFLAGS="$save_CXXFLAGS"
+LIBS="$kde_safe_LIBS"
+AC_LANG_RESTORE
+])
+
+AC_MSG_RESULT($kde_cv_func_$1)
+
+AC_MSG_CHECKING([if $1 needs custom prototype])
+AC_CACHE_VAL(kde_cv_proto_$1,
+[
+if test "x$kde_cv_func_$1" = xyes; then
+ kde_cv_proto_$1=no
+else
+ case "$1" in
+ setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat)
+ kde_cv_proto_$1="yes - in libkdefakes"
+ ;;
+ *)
+ kde_cv_proto_$1=unknown
+ ;;
+ esac
+fi
+
+if test "x$kde_cv_proto_$1" = xunknown; then
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ kde_safe_libs=$LIBS
+ LIBS="$LIBS $X_EXTRA_LIBS"
+ AC_TRY_LINK([
+$2
+
+extern "C" $4;
+],
+[
+$3
+],
+[ kde_cv_func_$1=yes
+ kde_cv_proto_$1=yes ],
+ [kde_cv_proto_$1="$1 unavailable"]
+)
+LIBS=$kde_safe_libs
+AC_LANG_RESTORE
+fi
+])
+AC_MSG_RESULT($kde_cv_proto_$1)
+
+if test "x$kde_cv_func_$1" = xyes; then
+ AC_DEFINE(HAVE_$5, 1, [Define if you have $1])
+ $6
+fi
+if test "x$kde_cv_proto_$1" = xno; then
+ AC_DEFINE(HAVE_$5_PROTO, 1,
+ [Define if you have the $1 prototype])
+fi
+
+AH_VERBATIM([_HAVE_$5_PROTO],
+[
+#if !defined(HAVE_$5_PROTO)
+#ifdef __cplusplus
+extern "C" {
+#endif
+$4;
+#ifdef __cplusplus
+}
+#endif
+#endif
+])
+])
+
+AC_DEFUN([AC_CHECK_SETENV],
+[
+ KDE_CHECK_FUNC_EXT(setenv, [
+#include <stdlib.h>
+],
+ [setenv("VAR", "VALUE", 1);],
+ [int setenv (const char *, const char *, int)],
+ [SETENV])
+])
+
+AC_DEFUN([AC_CHECK_UNSETENV],
+[
+ KDE_CHECK_FUNC_EXT(unsetenv, [
+#include <stdlib.h>
+],
+ [unsetenv("VAR");],
+ [void unsetenv (const char *)],
+ [UNSETENV])
+])
+
+AC_DEFUN([AC_CHECK_GETDOMAINNAME],
+[
+ KDE_CHECK_FUNC_EXT(getdomainname, [
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+],
+ [
+char buffer[200];
+getdomainname(buffer, 200);
+],
+ [#include <sys/types.h>
+ int getdomainname (char *, size_t)],
+ [GETDOMAINNAME])
+])
+
+AC_DEFUN([AC_CHECK_GETHOSTNAME],
+[
+ KDE_CHECK_FUNC_EXT(gethostname, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+char buffer[200];
+gethostname(buffer, 200);
+],
+ [int gethostname (char *, unsigned int)],
+ [GETHOSTNAME])
+])
+
+AC_DEFUN([AC_CHECK_USLEEP],
+[
+ KDE_CHECK_FUNC_EXT(usleep, [
+#include <unistd.h>
+],
+ [
+usleep(200);
+],
+ [int usleep (unsigned int)],
+ [USLEEP])
+])
+
+
+AC_DEFUN([AC_CHECK_RANDOM],
+[
+ KDE_CHECK_FUNC_EXT(random, [
+#include <stdlib.h>
+],
+ [
+random();
+],
+ [long int random(void)],
+ [RANDOM])
+
+ KDE_CHECK_FUNC_EXT(srandom, [
+#include <stdlib.h>
+],
+ [
+srandom(27);
+],
+ [void srandom(unsigned int)],
+ [SRANDOM])
+
+])
+
+AC_DEFUN([AC_CHECK_INITGROUPS],
+[
+ KDE_CHECK_FUNC_EXT(initgroups, [
+#include <sys/types.h>
+#include <unistd.h>
+#include <grp.h>
+],
+ [
+char buffer[200];
+initgroups(buffer, 27);
+],
+ [int initgroups(const char *, gid_t)],
+ [INITGROUPS])
+])
+
+AC_DEFUN([AC_CHECK_MKSTEMPS],
+[
+ KDE_CHECK_FUNC_EXT(mkstemps, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+mkstemps("/tmp/aaaXXXXXX", 6);
+],
+ [int mkstemps(char *, int)],
+ [MKSTEMPS])
+])
+
+AC_DEFUN([AC_CHECK_MKSTEMP],
+[
+ KDE_CHECK_FUNC_EXT(mkstemp, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+mkstemp("/tmp/aaaXXXXXX");
+],
+ [int mkstemp(char *)],
+ [MKSTEMP])
+])
+
+AC_DEFUN([AC_CHECK_MKDTEMP],
+[
+ KDE_CHECK_FUNC_EXT(mkdtemp, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+mkdtemp("/tmp/aaaXXXXXX");
+],
+ [char *mkdtemp(char *)],
+ [MKDTEMP])
+])
+
+
+AC_DEFUN([AC_CHECK_RES_INIT],
+[
+ AC_MSG_CHECKING([if res_init needs -lresolv])
+ kde_libs_safe="$LIBS"
+ LIBS="$LIBS $X_EXTRA_LIBS -lresolv"
+ AC_TRY_LINK(
+ [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+ ],
+ [
+ res_init();
+ ],
+ [
+ LIBRESOLV="-lresolv"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RES_INIT, 1, [Define if you have the res_init function])
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ LIBS=$kde_libs_safe
+ AC_SUBST(LIBRESOLV)
+
+ KDE_CHECK_FUNC_EXT(res_init,
+ [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+ ],
+ [res_init()],
+ [int res_init(void)],
+ [RES_INIT])
+])
+
+AC_DEFUN([AC_CHECK_STRLCPY],
+[
+ KDE_CHECK_FUNC_EXT(strlcpy, [
+#include <string.h>
+],
+[ char buf[20];
+ strlcpy(buf, "KDE function test", sizeof(buf));
+],
+ [unsigned long strlcpy(char*, const char*, unsigned long)],
+ [STRLCPY])
+])
+
+AC_DEFUN([AC_CHECK_STRLCAT],
+[
+ KDE_CHECK_FUNC_EXT(strlcat, [
+#include <string.h>
+],
+[ char buf[20];
+ buf[0]='\0';
+ strlcat(buf, "KDE function test", sizeof(buf));
+],
+ [unsigned long strlcat(char*, const char*, unsigned long)],
+ [STRLCAT])
+])
+
+AC_DEFUN([AC_CHECK_RES_QUERY],
+[
+ KDE_CHECK_FUNC_EXT(res_query, [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+],
+[
+res_query(NULL, 0, 0, NULL, 0);
+],
+ [int res_query(const char *, int, int, unsigned char *, int)],
+ [RES_QUERY])
+])
+
+AC_DEFUN([AC_CHECK_DN_SKIPNAME],
+[
+ KDE_CHECK_FUNC_EXT(dn_skipname, [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+],
+[
+dn_skipname (NULL, NULL);
+],
+ [int dn_skipname (unsigned char *, unsigned char *)],
+ [DN_SKIPNAME])
+])
+
+
+AC_DEFUN([AC_FIND_GIF],
+ [AC_MSG_CHECKING([for giflib])
+AC_CACHE_VAL(ac_cv_lib_gif,
+[ac_save_LIBS="$LIBS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$all_libraries -lgif -lX11 $LIBSOCKET"
+else
+LIBS="$all_libraries -lgif"
+fi
+AC_TRY_LINK(dnl
+[
+#ifdef __cplusplus
+extern "C" {
+#endif
+int GifLastError(void);
+#ifdef __cplusplus
+}
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+],
+ [return GifLastError();],
+ eval "ac_cv_lib_gif=yes",
+ eval "ac_cv_lib_gif=no")
+LIBS="$ac_save_LIBS"
+])dnl
+if eval "test \"`echo $ac_cv_lib_gif`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_LIBGIF, 1, [Define if you have libgif])
+else
+ AC_MSG_ERROR(You need giflib30. Please install the kdesupport package)
+fi
+])
+
+AC_DEFUN([KDE_FIND_JPEG_HELPER],
+[
+AC_MSG_CHECKING([for libjpeg$2])
+AC_CACHE_VAL(ac_cv_lib_jpeg_$1,
+[
+ac_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS -ljpeg$2 -lm"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(
+[
+#ifdef __cplusplus
+extern "C" {
+#endif
+void jpeg_CreateDecompress();
+#ifdef __cplusplus
+}
+#endif
+],
+[jpeg_CreateDecompress();],
+ eval "ac_cv_lib_jpeg_$1=-ljpeg$2",
+ eval "ac_cv_lib_jpeg_$1=no")
+LIBS="$ac_save_LIBS"
+CFLAGS="$ac_save_CFLAGS"
+])
+
+if eval "test ! \"`echo $ac_cv_lib_jpeg_$1`\" = no"; then
+ LIBJPEG="$ac_cv_lib_jpeg_$1"
+ AC_MSG_RESULT($ac_cv_lib_jpeg_$1)
+else
+ AC_MSG_RESULT(no)
+ $3
+fi
+
+])
+
+AC_DEFUN([AC_FIND_JPEG],
+[
+dnl first look for libraries
+KDE_FIND_JPEG_HELPER(6b, 6b,
+ KDE_FIND_JPEG_HELPER(normal, [],
+ [
+ LIBJPEG=
+ ]
+ )
+)
+
+dnl then search the headers (can't use simply AC_TRY_xxx, as jpeglib.h
+dnl requires system dependent includes loaded before it)
+jpeg_incdirs="$includedir /usr/include /usr/local/include $kde_extra_includes"
+AC_FIND_FILE(jpeglib.h, $jpeg_incdirs, jpeg_incdir)
+test "x$jpeg_incdir" = xNO && jpeg_incdir=
+
+dnl if headers _and_ libraries are missing, this is no error, and we
+dnl continue with a warning (the user will get no jpeg support in khtml)
+dnl if only one is missing, it means a configuration error, but we still
+dnl only warn
+if test -n "$jpeg_incdir" && test -n "$LIBJPEG" ; then
+ AC_DEFINE_UNQUOTED(HAVE_LIBJPEG, 1, [Define if you have libjpeg])
+else
+ if test -n "$jpeg_incdir" || test -n "$LIBJPEG" ; then
+ AC_MSG_WARN([
+There is an installation error in jpeg support. You seem to have only one
+of either the headers _or_ the libraries installed. You may need to either
+provide correct --with-extra-... options, or the development package of
+libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/
+Disabling JPEG support.
+])
+ else
+ AC_MSG_WARN([libjpeg not found. disable JPEG support.])
+ fi
+ jpeg_incdir=
+ LIBJPEG=
+fi
+
+AC_SUBST(LIBJPEG)
+AH_VERBATIM(_AC_CHECK_JPEG,
+[/*
+ * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system
+ * headers and I'm too lazy to write a configure test as long as only
+ * unixware is related
+ */
+#ifdef _UNIXWARE
+#define HAVE_BOOLEAN
+#endif
+])
+])
+
+AC_DEFUN([KDE_CHECK_QT_JPEG],
+[
+if test -n "$LIBJPEG"; then
+AC_MSG_CHECKING([if Qt needs $LIBJPEG])
+AC_CACHE_VAL(kde_cv_qt_jpeg,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ac_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS $LIBQT"
+LIBS=`echo $LIBS | sed "s/$LIBJPEG//"`
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(
+[#include <qapplication.h>],
+ [
+ int argc;
+ char** argv;
+ QApplication app(argc, argv);],
+ eval "kde_cv_qt_jpeg=no",
+ eval "kde_cv_qt_jpeg=yes")
+LIBS="$ac_save_LIBS"
+CXXFLAGS="$ac_save_CXXFLAGS"
+AC_LANG_RESTORE
+fi
+])
+
+if eval "test ! \"`echo $kde_cv_qt_jpeg`\" = no"; then
+ AC_MSG_RESULT(yes)
+ LIBJPEG_QT='$(LIBJPEG)'
+else
+ AC_MSG_RESULT(no)
+ LIBJPEG_QT=
+fi
+
+])
+
+AC_DEFUN([AC_FIND_ZLIB],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_MSG_CHECKING([for libz])
+AC_CACHE_VAL(ac_cv_lib_z,
+[
+kde_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS -lz $LIBSOCKET"
+kde_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(dnl
+[
+#include<zlib.h>
+#include<string.h>
+],
+[
+ char buf[42];
+ gzFile f = (gzFile) 0;
+ /* this would segfault.. but we only link, don't run */
+ (void) gzgets(f, buf, sizeof(buf));
+
+ return (strcmp(zlibVersion(), ZLIB_VERSION) == 0);
+],
+ eval "ac_cv_lib_z='-lz'",
+ eval "ac_cv_lib_z=no")
+LIBS="$kde_save_LIBS"
+CFLAGS="$kde_save_CFLAGS"
+])dnl
+if test ! "$ac_cv_lib_z" = no; then
+ AC_DEFINE_UNQUOTED(HAVE_LIBZ, 1, [Define if you have libz])
+ LIBZ="$ac_cv_lib_z"
+ AC_MSG_RESULT($ac_cv_lib_z)
+else
+ AC_MSG_ERROR(not found.
+ Possibly configure picks up an outdated version
+ installed by XFree86. Remove it from your system.
+
+ Check your installation and look into config.log)
+ LIBZ=""
+fi
+AC_SUBST(LIBZ)
+])
+
+AC_DEFUN([KDE_TRY_TIFFLIB],
+[
+AC_MSG_CHECKING([for libtiff $1])
+
+AC_CACHE_VAL(kde_cv_libtiff_$1,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+kde_save_LIBS="$LIBS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lX11 $LIBSOCKET -lm"
+else
+LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lm"
+fi
+kde_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES"
+
+AC_TRY_LINK(dnl
+[
+#include<tiffio.h>
+],
+ [return (TIFFOpen( "", "r") == 0); ],
+[
+ kde_cv_libtiff_$1="-l$1 $LIBJPEG $LIBZ"
+], [
+ kde_cv_libtiff_$1=no
+])
+
+LIBS="$kde_save_LIBS"
+CXXFLAGS="$kde_save_CXXFLAGS"
+AC_LANG_RESTORE
+])
+
+if test "$kde_cv_libtiff_$1" = "no"; then
+ AC_MSG_RESULT(no)
+ LIBTIFF=""
+ $3
+else
+ LIBTIFF="$kde_cv_libtiff_$1"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_LIBTIFF, 1, [Define if you have libtiff])
+ $2
+fi
+
+])
+
+AC_DEFUN([AC_FIND_TIFF],
+[
+AC_REQUIRE([K_PATH_X])
+AC_REQUIRE([AC_FIND_ZLIB])
+AC_REQUIRE([AC_FIND_JPEG])
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+KDE_TRY_TIFFLIB(tiff, [],
+ KDE_TRY_TIFFLIB(tiff34))
+
+AC_SUBST(LIBTIFF)
+])
+
+AC_DEFUN([KDE_FIND_LIBEXR],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_REQUIRE([AC_FIND_ZLIB])
+AC_CACHE_VAL(ac_cv_libexr,
+[
+ if test -z "$PKG_CONFIG"; then
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ fi
+
+ AC_MSG_CHECKING([for OpenEXR libraries])
+
+ if test "$PKG_CONFIG" = "no" ; then
+ AC_MSG_RESULT(no)
+ echo "*** The pkg-config script could not be found. Make sure it is"
+ echo "*** in your path, or set the PKG_CONFIG environment variable"
+ echo "*** to the full path to pkg-config."
+ echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+ else
+ if !(`$PKG_CONFIG --exists OpenEXR`) ; then
+ AC_MSG_RESULT(no)
+ EXRSTATUS=no
+ else
+ if !(`$PKG_CONFIG --atleast-version="1.1.1" OpenEXR`) ; then
+ AC_MSG_RESULT(no)
+ EXRSTATUS=old
+ else
+ kde_save_LIBS="$LIBS"
+ LIBS="$LIBS $all_libraries $USER_LDFLAGS `pkg-config --libs OpenEXR` $LIBZ"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ kde_save_CXXFLAGS="$CXXFLAGS"
+ EXR_FLAGS=`$PKG_CONFIG --cflags OpenEXR`
+ CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES $EXR_FLAGS"
+
+ AC_TRY_LINK(dnl
+ [
+ #include <ImfRgbaFile.h>
+ ],
+ [
+ using namespace Imf;
+ RgbaInputFile file ("dummy");
+ return 0;
+ ],
+ eval "ac_cv_libexr='`pkg-config --libs OpenEXR`'",
+ eval "ac_cv_libexr=no"
+ )
+ LIBS="$kde_save_LIBS"
+ CXXFLAGS="$kde_save_CXXFLAGS"
+ AC_LANG_RESTORE
+ ])dnl
+ if eval "test ! \"`echo $ac_cv_libexr`\" = no"; then
+ AC_DEFINE_UNQUOTED(HAVE_EXR, 1, [Define if you have OpenEXR])
+ LIB_EXR="$ac_cv_libexr"
+ AC_MSG_RESULT($ac_cv_libexr)
+ else
+ AC_MSG_RESULT(no)
+ LIB_EXR=""
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST(LIB_EXR)
+ AC_SUBST(EXR_FLAGS)
+])
+
+
+
+AC_DEFUN([AC_FIND_PNG],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_REQUIRE([AC_FIND_ZLIB])
+AC_MSG_CHECKING([for libpng])
+AC_CACHE_VAL(ac_cv_lib_png,
+[
+kde_save_LIBS="$LIBS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm -lX11 $LIBSOCKET"
+else
+LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm"
+fi
+kde_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+
+AC_TRY_LINK(dnl
+ [
+ #include<png.h>
+ ],
+ [
+ png_structp png_ptr = png_create_read_struct( /* image ptr */
+ PNG_LIBPNG_VER_STRING, 0, 0, 0 );
+ return( png_ptr != 0 );
+ ],
+ eval "ac_cv_lib_png='-lpng $LIBZ -lm'",
+ eval "ac_cv_lib_png=no"
+)
+LIBS="$kde_save_LIBS"
+CFLAGS="$kde_save_CFLAGS"
+])dnl
+if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then
+ AC_DEFINE_UNQUOTED(HAVE_LIBPNG, 1, [Define if you have libpng])
+ LIBPNG="$ac_cv_lib_png"
+ AC_SUBST(LIBPNG)
+ AC_MSG_RESULT($ac_cv_lib_png)
+else
+ AC_MSG_RESULT(no)
+ LIBPNG=""
+ AC_SUBST(LIBPNG)
+fi
+])
+
+
+AC_DEFUN([AC_FIND_JASPER],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_REQUIRE([AC_FIND_JPEG])
+AC_MSG_CHECKING([for jasper])
+AC_CACHE_VAL(ac_cv_jasper,
+[
+kde_save_LIBS="$LIBS"
+LIBS="$LIBS $all_libraries $USER_LDFLAGS -ljasper $LIBJPEG -lm"
+kde_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+
+AC_TRY_LINK(dnl
+ [
+ #include<jasper/jasper.h>
+ ],
+ [
+ return( jas_init() );
+ ],
+ eval "ac_cv_jasper='-ljasper $LIBJPEG -lm'",
+ eval "ac_cv_jasper=no"
+)
+LIBS="$kde_save_LIBS"
+CFLAGS="$kde_save_CFLAGS"
+])dnl
+if eval "test ! \"`echo $ac_cv_jasper`\" = no"; then
+ AC_DEFINE_UNQUOTED(HAVE_JASPER, 1, [Define if you have jasper])
+ LIB_JASPER="$ac_cv_jasper"
+ AC_MSG_RESULT($ac_cv_jasper)
+else
+ AC_MSG_RESULT(no)
+ LIB_JASPER=""
+fi
+AC_SUBST(LIB_JASPER)
+])
+
+AC_DEFUN([AC_CHECK_BOOL],
+[
+ AC_DEFINE_UNQUOTED(HAVE_BOOL, 1, [You _must_ have bool])
+])
+
+AC_DEFUN([AC_CHECK_GNU_EXTENSIONS],
+[
+AC_MSG_CHECKING(if you need GNU extensions)
+AC_CACHE_VAL(ac_cv_gnu_extensions,
+[
+cat > conftest.c << EOF
+#include <features.h>
+
+#ifdef __GNU_LIBRARY__
+yes
+#endif
+EOF
+
+if (eval "$ac_cpp conftest.c") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_gnu_extensions=yes
+else
+ ac_cv_gnu_extensions=no
+fi
+])
+
+AC_MSG_RESULT($ac_cv_gnu_extensions)
+if test "$ac_cv_gnu_extensions" = "yes"; then
+ AC_DEFINE_UNQUOTED(_GNU_SOURCE, 1, [Define if you need to use the GNU extensions])
+fi
+])
+
+AC_DEFUN([KDE_CHECK_COMPILER_FLAG],
+[
+AC_MSG_CHECKING([whether $CXX supports -$1])
+kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'`
+AC_CACHE_VAL(kde_cv_prog_cxx_$kde_cache,
+[
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -$1"
+ AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cxx_$kde_cache=yes"], [])
+ CXXFLAGS="$save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ :
+ $2
+else
+ AC_MSG_RESULT(no)
+ :
+ $3
+fi
+])
+
+AC_DEFUN([KDE_CHECK_C_COMPILER_FLAG],
+[
+AC_MSG_CHECKING([whether $CC supports -$1])
+kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'`
+AC_CACHE_VAL(kde_cv_prog_cc_$kde_cache,
+[
+ AC_LANG_SAVE
+ AC_LANG_C
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -$1"
+ AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cc_$kde_cache=yes"], [])
+ CFLAGS="$save_CFLAGS"
+ AC_LANG_RESTORE
+])
+if eval "test \"`echo '$kde_cv_prog_cc_'$kde_cache`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ :
+ $2
+else
+ AC_MSG_RESULT(no)
+ :
+ $3
+fi
+])
+
+
+dnl AC_REMOVE_FORBIDDEN removes forbidden arguments from variables
+dnl use: AC_REMOVE_FORBIDDEN(CC, [-forbid -bad-option whatever])
+dnl it's all white-space separated
+AC_DEFUN([AC_REMOVE_FORBIDDEN],
+[ __val=$$1
+ __forbid=" $2 "
+ if test -n "$__val"; then
+ __new=""
+ ac_save_IFS=$IFS
+ IFS=" "
+ for i in $__val; do
+ case "$__forbid" in
+ *" $i "*) AC_MSG_WARN([found forbidden $i in $1, removing it]) ;;
+ *) # Careful to not add spaces, where there were none, because otherwise
+ # libtool gets confused, if we change e.g. CXX
+ if test -z "$__new" ; then __new=$i ; else __new="$__new $i" ; fi ;;
+ esac
+ done
+ IFS=$ac_save_IFS
+ $1=$__new
+ fi
+])
+
+
+AC_DEFUN([KDE_CHECK_FOR_BAD_COMPILER],
+[
+ AC_MSG_CHECKING([whether $CC is blacklisted])
+
+ dnl In theory we have tu run this test against $CC and $CXX
+ dnl in C and in C++ mode, because its perfectly legal for
+ dnl the user to mix compiler versions, since C has a defined
+ dnl ABI.
+ dnl
+ dnl For now, we assume the user is not on crack.
+
+ AC_TRY_COMPILE([
+#ifdef __GNUC__
+#if __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 0
+choke me
+#endif
+#endif
+], ,
+ kde_bad_compiler=no,
+ kde_bad_compiler=yes
+)
+
+ AC_MSG_RESULT($kde_bad_compiler)
+
+if test "$kde_bad_compiler" = "yes"; then
+ AC_MSG_ERROR([
+
+This particular compiler version is blacklisted because it
+is known to miscompile KDE. Please use a newer version, or
+if that is not yet available, choose an older version.
+
+Please do not report a bug or bother us reporting this
+configure error. We know about it, and we introduced
+it by intention to avoid untraceable bugs or crashes in KDE.
+
+])
+fi
+
+])
+
+
+AC_DEFUN([KDE_CHECK_FOR_OPT_NOINLINE_MATCH],
+[
+ AC_CACHE_CHECK([whether system headers can cope with -O2 -fno-inline],
+ kde_cv_opt_noinline_match,
+ [
+ kde_cv_opt_noinline_match=irrelevant
+ dnl if we don't use both -O2 and -fno-inline, this check is moot
+ if echo "$CFLAGS" | grep -e -O2 >/dev/null 2>/dev/null \
+ && echo "$CFLAGS" | grep -e -fno-inline >/dev/null 2>/dev/null ; then
+
+ ac_cflags_save="$CFLAGS"
+ CFLAGS="$CFLAGS -D_USE_GNU"
+
+ AC_TRY_LINK([
+ #include <string.h>
+], [ const char *pt, *et;
+ et = __extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p ( ";," ) && ((size_t)(const void *)(( ";," )+ 1) - (size_t)(const void *)( ";," ) == 1) ? ((__a0 =((__const char *) ( ";," ))[0], __a0 == '\0') ? ((void) ( pt ),((void *)0) ) : ((__a1 = ((__const char *) ( ";," ))[1], __a1== '\0') ? (__extension__ (__builtin_constant_p ( __a0 ) && ( __a0 ) == '\0' ? (char *) __rawmemchr ( pt , __a0) : strchr( pt , __a0 ))) : ((__a2 = ((__const char *) ( ";," ))[2], __a2 == '\0') ? __strpbrk_c2 ( pt , __a0, __a1) :(((__const char *) ( ";," ))[3] == '\0' ? __strpbrk_c3 ( pt ,__a0, __a1, __a2): strpbrk ( pt , ";," ))))) : strpbrk ( pt , ";," )); }) ;
+],
+ kde_cv_opt_noinline_match=yes,
+ kde_cv_opt_noinline_match=no
+ )
+
+ CFLAGS="$ac_cflags_save"
+ fi
+ ])
+])
+
+
+dnl AC_VALIDIFY_CXXFLAGS checks for forbidden flags the user may have given
+AC_DEFUN([AC_VALIDIFY_CXXFLAGS],
+[dnl
+if test "x$kde_use_qt_emb" != "xyes"; then
+ AC_REMOVE_FORBIDDEN(CXX, [-fno-rtti -rpath])
+ AC_REMOVE_FORBIDDEN(CXXFLAGS, [-fno-rtti -rpath])
+else
+ AC_REMOVE_FORBIDDEN(CXX, [-rpath])
+ AC_REMOVE_FORBIDDEN(CXXFLAGS, [-rpath])
+fi
+])
+
+AC_DEFUN([AC_CHECK_COMPILERS],
+[
+ AC_ARG_ENABLE(debug,
+ AC_HELP_STRING([--enable-debug=ARG],[enables debug symbols (yes|no|full) [default=no]]),
+ [
+ case $enableval in
+ yes)
+ kde_use_debug_code="yes"
+ kde_use_debug_define=no
+ ;;
+ full)
+ kde_use_debug_code="full"
+ kde_use_debug_define=no
+ ;;
+ *)
+ kde_use_debug_code="no"
+ kde_use_debug_define=yes
+ ;;
+ esac
+ ],
+ [kde_use_debug_code="no"
+ kde_use_debug_define=no
+ ])
+
+ dnl Just for configure --help
+ AC_ARG_ENABLE(dummyoption,
+ AC_HELP_STRING([--disable-debug],
+ [disables debug output and debug symbols [default=no]]),
+ [],[])
+
+ AC_ARG_ENABLE(strict,
+ AC_HELP_STRING([--enable-strict],
+ [compiles with strict compiler options (may not work!)]),
+ [
+ if test $enableval = "no"; then
+ kde_use_strict_options="no"
+ else
+ kde_use_strict_options="yes"
+ fi
+ ], [kde_use_strict_options="no"])
+
+ AC_ARG_ENABLE(warnings,AC_HELP_STRING([--disable-warnings],[disables compilation with -Wall and similar]),
+ [
+ if test $enableval = "no"; then
+ kde_use_warnings="no"
+ else
+ kde_use_warnings="yes"
+ fi
+ ], [kde_use_warnings="yes"])
+
+ dnl enable warnings for debug build
+ if test "$kde_use_debug_code" != "no"; then
+ kde_use_warnings=yes
+ fi
+
+ AC_ARG_ENABLE(profile,AC_HELP_STRING([--enable-profile],[creates profiling infos [default=no]]),
+ [kde_use_profiling=$enableval],
+ [kde_use_profiling="no"]
+ )
+
+ dnl this prevents stupid AC_PROG_CC to add "-g" to the default CFLAGS
+ CFLAGS=" $CFLAGS"
+
+ AC_PROG_CC
+
+ AC_PROG_CPP
+
+ if test "$GCC" = "yes"; then
+ if test "$kde_use_debug_code" != "no"; then
+ if test $kde_use_debug_code = "full"; then
+ CFLAGS="-g3 -fno-inline $CFLAGS"
+ else
+ CFLAGS="-g -O2 -fno-schedule-insns -fno-inline $CFLAGS"
+ fi
+ else
+ CFLAGS="-O2 $CFLAGS"
+ fi
+ fi
+
+ if test "$kde_use_debug_define" = "yes"; then
+ CFLAGS="-DNDEBUG $CFLAGS"
+ fi
+
+
+ case "$host" in
+ *-*-sysv4.2uw*) CFLAGS="-D_UNIXWARE $CFLAGS";;
+ *-*-sysv5uw7*) CFLAGS="-D_UNIXWARE7 $CFLAGS";;
+ esac
+
+ if test -z "$LDFLAGS" && test "$kde_use_debug_code" = "no" && test "$GCC" = "yes"; then
+ LDFLAGS=""
+ fi
+
+ CXXFLAGS=" $CXXFLAGS"
+
+ AC_PROG_CXX
+
+ KDE_CHECK_FOR_BAD_COMPILER
+
+ if test "$GXX" = "yes" || test "$CXX" = "KCC"; then
+ if test "$kde_use_debug_code" != "no"; then
+ if test "$CXX" = "KCC"; then
+ CXXFLAGS="+K0 -Wall -pedantic -W -Wpointer-arith -Wwrite-strings $CXXFLAGS"
+ else
+ if test "$kde_use_debug_code" = "full"; then
+ CXXFLAGS="-g3 -fno-inline $CXXFLAGS"
+ else
+ CXXFLAGS="-g -O2 -fno-schedule-insns -fno-inline $CXXFLAGS"
+ fi
+ fi
+ KDE_CHECK_COMPILER_FLAG(fno-builtin,[CXXFLAGS="-fno-builtin $CXXFLAGS"])
+
+ dnl convenience compiler flags
+ KDE_CHECK_COMPILER_FLAG(Woverloaded-virtual, [WOVERLOADED_VIRTUAL="-Woverloaded-virtual"], [WOVERLOADED_VRITUAL=""])
+ AC_SUBST(WOVERLOADED_VIRTUAL)
+ else
+ if test "$CXX" = "KCC"; then
+ CXXFLAGS="+K3 $CXXFLAGS"
+ else
+ CXXFLAGS="-O2 $CXXFLAGS"
+ fi
+ fi
+ fi
+
+ if test "$kde_use_debug_define" = "yes"; then
+ CXXFLAGS="-DNDEBUG -DNO_DEBUG $CXXFLAGS"
+ fi
+
+ if test "$kde_use_profiling" = "yes"; then
+ KDE_CHECK_COMPILER_FLAG(pg,
+ [
+ CFLAGS="-pg $CFLAGS"
+ CXXFLAGS="-pg $CXXFLAGS"
+ ])
+ fi
+
+ if test "$kde_use_warnings" = "yes"; then
+ if test "$GCC" = "yes"; then
+ CXXFLAGS="-Wall -W -Wpointer-arith $CXXFLAGS"
+ case $host in
+ *-*-linux-gnu)
+ CFLAGS="-std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE $CFLAGS"
+ CXXFLAGS="-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wchar-subscripts $CXXFLAGS"
+ KDE_CHECK_COMPILER_FLAG(Wmissing-format-attribute, [CXXFLAGS="$CXXFLAGS -Wformat-security -Wmissing-format-attribute"])
+ KDE_CHECK_C_COMPILER_FLAG(Wmissing-format-attribute, [CFLAGS="$CFLAGS -Wformat-security -Wmissing-format-attribute"])
+ ;;
+ esac
+ KDE_CHECK_COMPILER_FLAG(Wundef,[CXXFLAGS="-Wundef $CXXFLAGS"])
+ KDE_CHECK_COMPILER_FLAG(Wno-long-long,[CXXFLAGS="-Wno-long-long $CXXFLAGS"])
+ dnl ### FIXME: revert for KDE 4
+ KDE_CHECK_COMPILER_FLAG(Wno-non-virtual-dtor,[CXXFLAGS="$CXXFLAGS -Wno-non-virtual-dtor"])
+ fi
+ fi
+
+ if test "$GXX" = "yes" && test "$kde_use_strict_options" = "yes"; then
+ CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS"
+ fi
+
+ AC_ARG_ENABLE(pch,
+ AC_HELP_STRING([--enable-pch],
+ [enables precompiled header support (currently only KCC or gcc >=3.4+unsermake) [default=no]]),
+ [ kde_use_pch=$enableval ],[ kde_use_pch=no ])
+
+ HAVE_GCC_VISIBILITY=0
+ AC_SUBST([HAVE_GCC_VISIBILITY])
+
+ if test "$GXX" = "yes"; then
+ gcc_no_reorder_blocks=NO
+ KDE_CHECK_COMPILER_FLAG(fno-reorder-blocks,[gcc_no_reorder_blocks=YES])
+ if test $kde_use_debug_code != "no" && \
+ test $kde_use_debug_code != "full" && \
+ test "YES" = "$gcc_no_reorder_blocks" ; then
+ CXXFLAGS="$CXXFLAGS -fno-reorder-blocks"
+ CFLAGS="$CFLAGS -fno-reorder-blocks"
+ fi
+ KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"])
+ KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"])
+ KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"])
+ KDE_CHECK_COMPILER_FLAG(fexceptions, [USE_EXCEPTIONS="-fexceptions"], USE_EXCEPTIONS= )
+ ENABLE_PERMISSIVE_FLAG="-fpermissive"
+
+ if test "$kde_use_pch" = "yes"; then
+ AC_MSG_CHECKING(whether gcc supports precompiling c header files)
+ echo >conftest.h
+ if $CC -x c-header conftest.h >/dev/null 2>/dev/null; then
+ kde_gcc_supports_pch=yes
+ AC_MSG_RESULT(yes)
+ else
+ kde_gcc_supports_pch=no
+ AC_MSG_RESULT(no)
+ fi
+ if test "$kde_gcc_supports_pch" = "yes"; then
+ AC_MSG_CHECKING(whether gcc supports precompiling c++ header files)
+ if $CXX -x c++-header conftest.h >/dev/null 2>/dev/null; then
+ kde_gcc_supports_pch=yes
+ AC_MSG_RESULT(yes)
+ else
+ kde_gcc_supports_pch=no
+ AC_MSG_RESULT(no)
+ fi
+ fi
+ rm -f conftest.h conftest.h.gch
+ fi
+
+ KDE_CHECK_FOR_OPT_NOINLINE_MATCH
+ if test "x$kde_cv_opt_noinline_match" = "xno" ; then
+ CFLAGS="`echo "$CFLAGS" | sed "s/ -fno-inline//"`"
+ fi
+ fi
+ AM_CONDITIONAL(unsermake_enable_pch, test "$kde_use_pch" = "yes" && test "$kde_gcc_supports_pch" = "yes")
+ if test "$CXX" = "KCC"; then
+ dnl unfortunately we currently cannot disable exception support in KCC
+ dnl because doing so is binary incompatible and Qt by default links with exceptions :-(
+ dnl KDE_CHECK_COMPILER_FLAG(-no_exceptions,[CXXFLAGS="$CXXFLAGS --no_exceptions"])
+ dnl KDE_CHECK_COMPILER_FLAG(-exceptions, [USE_EXCEPTIONS="--exceptions"], USE_EXCEPTIONS= )
+
+ if test "$kde_use_pch" = "yes"; then
+ dnl TODO: support --pch-dir!
+ KDE_CHECK_COMPILER_FLAG(-pch,[CXXFLAGS="$CXXFLAGS --pch"])
+ dnl the below works (but the dir must exist), but it's
+ dnl useless for a whole package.
+ dnl The are precompiled headers for each source file, so when compiling
+ dnl from scratch, it doesn't make a difference, and they take up
+ dnl around ~5Mb _per_ sourcefile.
+ dnl KDE_CHECK_COMPILER_FLAG(-pch_dir /tmp,
+ dnl [CXXFLAGS="$CXXFLAGS --pch_dir `pwd`/pcheaders"])
+ fi
+ dnl this flag controls inlining. by default KCC inlines in optimisation mode
+ dnl all implementations that are defined inside the class {} declaration.
+ dnl because of templates-compatibility with broken gcc compilers, this
+ dnl can cause excessive inlining. This flag limits it to a sane level
+ KDE_CHECK_COMPILER_FLAG(-inline_keyword_space_time=6,[CXXFLAGS="$CXXFLAGS --inline_keyword_space_time=6"])
+ KDE_CHECK_COMPILER_FLAG(-inline_auto_space_time=2,[CXXFLAGS="$CXXFLAGS --inline_auto_space_time=2"])
+ KDE_CHECK_COMPILER_FLAG(-inline_implicit_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_implicit_space_time=2.0"])
+ KDE_CHECK_COMPILER_FLAG(-inline_generated_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_generated_space_time=2.0"])
+ dnl Some source files are shared between multiple executables
+ dnl (or libraries) and some of those need template instantiations.
+ dnl In that case KCC needs to compile those sources with
+ dnl --one_instantiation_per_object. To make it easy for us we compile
+ dnl _all_ objects with that flag (--one_per is a shorthand).
+ KDE_CHECK_COMPILER_FLAG(-one_per, [CXXFLAGS="$CXXFLAGS --one_per"])
+ fi
+ AC_SUBST(USE_EXCEPTIONS)
+ dnl obsolete macro - provided to keep things going
+ USE_RTTI=
+ AC_SUBST(USE_RTTI)
+
+ case "$host" in
+ *-*-irix*) test "$GXX" = yes && CXXFLAGS="-D_LANGUAGE_C_PLUS_PLUS -D__LANGUAGE_C_PLUS_PLUS $CXXFLAGS" ;;
+ *-*-sysv4.2uw*) CXXFLAGS="-D_UNIXWARE $CXXFLAGS";;
+ *-*-sysv5uw7*) CXXFLAGS="-D_UNIXWARE7 $CXXFLAGS";;
+ *-*-solaris*)
+ if test "$GXX" = yes; then
+ libstdcpp=`$CXX -print-file-name=libstdc++.so`
+ if test ! -f $libstdcpp; then
+ AC_MSG_ERROR([You've compiled gcc without --enable-shared. This doesn't work with KDE. Please recompile gcc with --enable-shared to receive a libstdc++.so])
+ fi
+ fi
+ ;;
+ esac
+
+ AC_VALIDIFY_CXXFLAGS
+
+ AC_PROG_CXXCPP
+
+ if test "$GCC" = yes; then
+ NOOPT_CFLAGS=-O0
+ fi
+ KDE_CHECK_COMPILER_FLAG(O0,[NOOPT_CXXFLAGS=-O0])
+
+ AC_ARG_ENABLE(coverage,
+ AC_HELP_STRING([--enable-coverage],[use gcc coverage testing]), [
+ if test "$am_cv_CC_dependencies_compiler_type" = "gcc3"; then
+ ac_coverage_compiler="-fprofile-arcs -ftest-coverage"
+ ac_coverage_linker="-lgcc"
+ elif test "$am_cv_CC_dependencies_compiler_type" = "gcc"; then
+ ac_coverage_compiler="-fprofile-arcs -ftest-coverage"
+ ac_coverage_linker=""
+ else
+ AC_MSG_ERROR([coverage with your compiler is not supported])
+ fi
+ CFLAGS="$CFLAGS $ac_coverage_compiler"
+ CXXFLAGS="$CXXFLAGS $ac_coverage_compiler"
+ LDFLAGS="$LDFLAGS $ac_coverage_linker"
+ ])
+
+ AC_SUBST(NOOPT_CXXFLAGS)
+ AC_SUBST(NOOPT_CFLAGS)
+ AC_SUBST(ENABLE_PERMISSIVE_FLAG)
+
+ KDE_CHECK_NEW_LDFLAGS
+ KDE_CHECK_FINAL
+ KDE_CHECK_CLOSURE
+ KDE_CHECK_NMCHECK
+
+ ifdef([AM_DEPENDENCIES], AC_REQUIRE([KDE_ADD_DEPENDENCIES]), [])
+])
+
+AC_DEFUN([KDE_CHECK_VISIBILITY_GCC_BUG],
+ [
+ AC_CACHE_CHECK([for gcc -fvisibility-inlines-hidden bug], kde_cv_val_gcc_visibility_bug,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ safe_CXXFLAGS=$CXXFLAGS
+ safe_LDFLAGS=$LDFLAGS
+ CXXFLAGS="$CXXFLAGS -fPIC -fvisibility-inlines-hidden -O0"
+ LDFLAGS="$LDFLAGS -shared -fPIC"
+
+ AC_TRY_LINK(
+ [
+ /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19664 */
+ #include <string>
+ int some_function( void ) __attribute__ ((visibility("default")));
+ int some_function( void )
+ {
+ std::string s("blafasel");
+ return 0;
+ }
+ ], [/* elvis is alive */],
+ kde_cv_val_gcc_visibility_bug=no, kde_cv_val_gcc_visibility_bug=yes)
+
+ CXXFLAGS=$safe_CXXFLAGS
+ LDFLAGS=$safe_LDFLAGS
+ AC_LANG_RESTORE
+ ]
+ )
+
+ if test x$kde_cv_val_gcc_visibility_bug = xno; then
+ CXXFLAGS="$CXXFLAGS -fvisibility-inlines-hidden"
+ fi
+ ]
+)
+
+AC_DEFUN([KDE_ENABLE_HIDDEN_VISIBILITY],
+[
+ AC_BEFORE([AC_PATH_QT_1_3], [KDE_ENABLE_HIDDEN_VISIBILITY])
+
+ AC_MSG_CHECKING([grepping for visibility push/pop in headers])
+
+ if test "x$GXX" = "xyes"; then
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_EGREP_CPP(
+ [GCC visibility push],
+ [ #include <exception>
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ kde_stdc_visibility_patched=yes ],
+ [
+ AC_MSG_RESULT(no)
+ AC_MSG_WARN([Your libstdc++ doesn't appear to be patched for
+ visibility support. Disabling -fvisibility=hidden])
+
+ kde_stdc_visibility_patched=no ])
+
+ AC_LANG_RESTORE
+
+ kde_have_gcc_visibility=no
+ KDE_CHECK_COMPILER_FLAG(fvisibility=hidden,
+ [
+ kde_have_gcc_visibility=yes
+ dnl the whole toolchain is just a mess, gcc is just too buggy
+ dnl to handle STL with visibility enabled. Lets reconsider
+ dnl when gcc 4.2 is out or when things get fixed in the compiler.
+ dnl Contact mueller@kde.org for details.
+ AC_ARG_ENABLE(gcc-hidden-visibility,
+ AC_HELP_STRING([--enable-gcc-hidden-visibility],[toolchain hidden visibility [default=no]]),
+ [kde_have_gcc_visibility=$enableval],
+ [kde_have_gcc_visibility=no])
+
+ AC_CACHE_CHECK([if Qt is patched for -fvisibility], kde_cv_val_qt_gcc_visibility_patched,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ safe_CXXFLAGS=$CXXFLAGS
+ CXXFLAGS="$CXXFLAGS $all_includes"
+
+ AC_TRY_COMPILE(
+ [
+#include <qglobal.h>
+#if Q_EXPORT - 0 != 0
+/* if this compiles, then Q_EXPORT is undefined */
+/* if Q_EXPORT is nonempty, this will break compilation */
+#endif
+ ], [/* elvis is alive */],
+ kde_cv_val_qt_gcc_visibility_patched=no, kde_cv_val_qt_gcc_visibility_patched=yes)
+
+ CXXFLAGS=$safe_CXXFLAGS
+ AC_LANG_RESTORE
+ ]
+ )
+
+ if test x$kde_have_gcc_visibility = "xyes" && test x$kde_stdc_visibility_patched = "xyes" && test x$kde_cv_val_qt_gcc_visibility_patched = "xyes"; then
+ CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
+ KDE_CHECK_VISIBILITY_GCC_BUG
+ HAVE_GCC_VISIBILITY=1
+ AC_DEFINE_UNQUOTED(__KDE_HAVE_GCC_VISIBILITY, "$HAVE_GCC_VISIBILITY", [define to 1 if -fvisibility is supported])
+ fi
+ ])
+ fi
+])
+
+AC_DEFUN([KDE_ADD_DEPENDENCIES],
+[
+ [A]M_DEPENDENCIES(CC)
+ [A]M_DEPENDENCIES(CXX)
+])
+
+dnl just a wrapper to clean up configure.in
+AC_DEFUN([KDE_PROG_LIBTOOL],
+[
+AC_REQUIRE([AC_CHECK_COMPILERS])
+AC_REQUIRE([AC_ENABLE_SHARED])
+AC_REQUIRE([AC_ENABLE_STATIC])
+
+AC_REQUIRE([AC_LIBTOOL_DLOPEN])
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+AC_OBJEXT
+AC_EXEEXT
+
+AM_PROG_LIBTOOL
+AC_LIBTOOL_CXX
+
+LIBTOOL_SHELL="/bin/sh ./libtool"
+# LIBTOOL="$LIBTOOL --silent"
+KDE_PLUGIN="-avoid-version -module -no-undefined \$(KDE_NO_UNDEFINED) \$(KDE_RPATH) \$(KDE_MT_LDFLAGS)"
+AC_SUBST(KDE_PLUGIN)
+
+# This hack ensures that libtool creates shared libs for kunittest plugins. By default check_LTLIBRARIES makes static libs.
+KDE_CHECK_PLUGIN="\$(KDE_PLUGIN) -rpath \$(libdir)"
+AC_SUBST(KDE_CHECK_PLUGIN)
+
+# we patch configure quite some so we better keep that consistent for incremental runs
+AC_SUBST(AUTOCONF,'$(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure')
+])
+
+AC_DEFUN([KDE_CHECK_LIB64],
+[
+ AC_ARG_ENABLE(libsuffix,
+ AC_HELP_STRING([--enable-libsuffix],
+ [/lib directory suffix (64,32,none,auto[=default])]),
+ kdelibsuff=$enableval, kdelibsuff="auto")
+
+ if test "$kdelibsuff" = "auto"; then
+
+cat > conftest.c << EOF
+#include <stdio.h>
+int main() {
+ return 0;
+}
+EOF
+ kdelibsuff=`$CC conftest.c -o conftest.out; ldd conftest.out |sed -ne '/libc.so/{
+ s,.*/lib\([[^\/]]*\)/.*,\1,
+ p
+}'`
+ rm -rf conftest.*
+ fi
+
+ if test "$kdelibsuff" = "no" || test "$kdelibsuff" = "none"; then
+ kdelibsuff=
+ fi
+ if test -z "$kdelibsuff"; then
+ AC_MSG_RESULT([not using lib directory suffix])
+ AC_DEFINE(KDELIBSUFF, [""], Suffix for lib directories)
+ else
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ libdir="$libdir${kdelibsuff}"
+ AC_SUBST([libdir], ["$libdir"]) dnl ugly hack for lib64 platforms
+ fi
+ AC_DEFINE_UNQUOTED(KDELIBSUFF, ["${kdelibsuff}"], Suffix for lib directories)
+ AC_MSG_RESULT([using lib directory suffix $kdelibsuff])
+ fi
+])
+
+AC_DEFUN([KDE_CHECK_TYPES],
+[ AC_CHECK_SIZEOF(int, 4)dnl
+ AC_CHECK_SIZEOF(short)dnl
+ AC_CHECK_SIZEOF(long, 4)dnl
+ AC_CHECK_SIZEOF(char *, 4)dnl
+])dnl
+
+dnl Not used - kept for compat only?
+AC_DEFUN([KDE_DO_IT_ALL],
+[
+AC_CANONICAL_SYSTEM
+AC_ARG_PROGRAM
+AM_INIT_AUTOMAKE($1, $2)
+AM_DISABLE_LIBRARIES
+AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde})
+AC_CHECK_COMPILERS
+KDE_PROG_LIBTOOL
+AM_KDE_WITH_NLS
+AC_PATH_KDE
+])
+
+AC_DEFUN([AC_CHECK_RPATH],
+[
+AC_MSG_CHECKING(for rpath)
+AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],[do not use the rpath feature of ld]),
+ USE_RPATH=$enableval, USE_RPATH=yes)
+
+if test -z "$KDE_RPATH" && test "$USE_RPATH" = "yes"; then
+
+ KDE_RPATH="-R \$(libdir)"
+
+ if test "$kde_libraries" != "$libdir"; then
+ KDE_RPATH="$KDE_RPATH -R \$(kde_libraries)"
+ fi
+
+ if test -n "$qt_libraries"; then
+ KDE_RPATH="$KDE_RPATH -R \$(qt_libraries)"
+ fi
+ dnl $x_libraries is set to /usr/lib in case
+ if test -n "$X_LDFLAGS"; then
+ X_RPATH="-R \$(x_libraries)"
+ KDE_RPATH="$KDE_RPATH $X_RPATH"
+ fi
+ if test -n "$KDE_EXTRA_RPATH"; then
+ KDE_RPATH="$KDE_RPATH \$(KDE_EXTRA_RPATH)"
+ fi
+fi
+AC_SUBST(KDE_EXTRA_RPATH)
+AC_SUBST(KDE_RPATH)
+AC_SUBST(X_RPATH)
+AC_MSG_RESULT($USE_RPATH)
+])
+
+dnl Check for the type of the third argument of getsockname
+AC_DEFUN([AC_CHECK_SOCKLEN_T],
+[
+ AC_MSG_CHECKING(for socklen_t)
+ AC_CACHE_VAL(kde_cv_socklen_t,
+ [
+ AC_LANG_PUSH(C++)
+ kde_cv_socklen_t=no
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ ],
+ [
+ socklen_t len;
+ getpeername(0,0,&len);
+ ],
+ [
+ kde_cv_socklen_t=yes
+ kde_cv_socklen_t_equiv=socklen_t
+ ])
+ AC_LANG_POP(C++)
+ ])
+ AC_MSG_RESULT($kde_cv_socklen_t)
+ if test $kde_cv_socklen_t = no; then
+ AC_MSG_CHECKING([for socklen_t equivalent for socket functions])
+ AC_CACHE_VAL(kde_cv_socklen_t_equiv,
+ [
+ kde_cv_socklen_t_equiv=int
+ AC_LANG_PUSH(C++)
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ ],
+ [
+ $t len;
+ getpeername(0,0,&len);
+ ],
+ [
+ kde_cv_socklen_t_equiv="$t"
+ break
+ ])
+ done
+ AC_LANG_POP(C++)
+ ])
+ AC_MSG_RESULT($kde_cv_socklen_t_equiv)
+ fi
+ AC_DEFINE_UNQUOTED(kde_socklen_t, $kde_cv_socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])
+ AC_DEFINE_UNQUOTED(ksize_t, $kde_cv_socklen_t_equiv,
+ [type to use in place of socklen_t if not defined (deprecated, use kde_socklen_t)])
+])
+
+dnl This is a merge of some macros out of the gettext aclocal.m4
+dnl since we don't need anything, I took the things we need
+dnl the copyright for them is:
+dnl >
+dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+dnl This Makefile.in is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+dnl >
+dnl for this file it is relicensed under LGPL
+
+AC_DEFUN([AM_KDE_WITH_NLS],
+ [
+ dnl If we use NLS figure out what method
+
+ AM_PATH_PROG_WITH_TEST_KDE(MSGFMT, msgfmt,
+ [test -n "`$ac_dir/$ac_word --version 2>&1 | grep 'GNU gettext'`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+
+ if test -z "`$GMSGFMT --version 2>&1 | grep 'GNU gettext'`"; then
+ AC_MSG_RESULT([found msgfmt program is not GNU msgfmt; ignore it])
+ GMSGFMT=":"
+ fi
+ MSGFMT=$GMSGFMT
+ AC_SUBST(GMSGFMT)
+ AC_SUBST(MSGFMT)
+
+ AM_PATH_PROG_WITH_TEST_KDE(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+ AC_SUBST(XGETTEXT)
+
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+# serial 1
+# Stephan Kulow: I appended a _KDE against name conflicts
+
+dnl AM_PATH_PROG_WITH_TEST_KDE(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST_KDE],
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# serial 1
+
+AC_DEFUN([AM_LC_MESSAGES],
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your locale.h file contains LC_MESSAGES])
+ fi
+ fi])
+
+dnl From Jim Meyering.
+dnl FIXME: migrate into libit.
+
+AC_DEFUN([AM_FUNC_OBSTACK],
+[AC_CACHE_CHECK([for obstacks], am_cv_func_obstack,
+ [AC_TRY_LINK([#include "obstack.h"],
+ [struct obstack *mem;obstack_free(mem,(char *) 0)],
+ am_cv_func_obstack=yes,
+ am_cv_func_obstack=no)])
+ if test $am_cv_func_obstack = yes; then
+ AC_DEFINE(HAVE_OBSTACK)
+ else
+ LIBOBJS="$LIBOBJS obstack.o"
+ fi
+])
+
+dnl From Jim Meyering. Use this if you use the GNU error.[ch].
+dnl FIXME: Migrate into libit
+
+AC_DEFUN([AM_FUNC_ERROR_AT_LINE],
+[AC_CACHE_CHECK([for error_at_line], am_cv_lib_error_at_line,
+ [AC_TRY_LINK([],[error_at_line(0, 0, "", 0, "");],
+ am_cv_lib_error_at_line=yes,
+ am_cv_lib_error_at_line=no)])
+ if test $am_cv_lib_error_at_line = no; then
+ LIBOBJS="$LIBOBJS error.o"
+ fi
+ AC_SUBST(LIBOBJS)dnl
+])
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# serial 1
+# Stephan Kulow: I put a KDE in it to avoid name conflicts
+
+AC_DEFUN([AM_KDE_GNU_GETTEXT],
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+ AC_REQUIRE([AM_KDE_WITH_NLS])dnl
+ AC_CHECK_HEADERS([limits.h locale.h nl_types.h string.h values.h alloca.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ AC_MSG_CHECKING(for stpcpy)
+ AC_CACHE_VAL(kde_cv_func_stpcpy,
+ [
+ kde_safe_cxxflags=$CXXFLAGS
+ CXXFLAGS="-Werror"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+ #include <string.h>
+ ],
+ [
+ char buffer[200];
+ stpcpy(buffer, buffer);
+ ],
+ kde_cv_func_stpcpy=yes,
+ kde_cv_func_stpcpy=no)
+ AC_LANG_RESTORE
+ CXXFLAGS=$kde_safe_cxxflags
+ ])
+ AC_MSG_RESULT($kde_cv_func_stpcpy)
+ if eval "test \"`echo $kde_cv_func_stpcpy`\" = yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have stpcpy])
+ fi
+
+ AM_LC_MESSAGES
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ ])
+
+AC_DEFUN([AC_HAVE_XPM],
+ [AC_REQUIRE_CPP()dnl
+ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+ test -z "$XPM_LDFLAGS" && XPM_LDFLAGS=
+ test -z "$XPM_INCLUDE" && XPM_INCLUDE=
+
+ AC_ARG_WITH(xpm,AC_HELP_STRING([--without-xpm],[disable color pixmap XPM tests]),
+ xpm_test=$withval, xpm_test="yes")
+ if test "x$xpm_test" = xno; then
+ ac_cv_have_xpm=no
+ else
+ AC_MSG_CHECKING(for XPM)
+ AC_CACHE_VAL(ac_cv_have_xpm,
+ [
+ ac_save_ldflags="$LDFLAGS"
+ ac_save_cflags="$CFLAGS"
+ if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+ LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm -lX11 -lXext $LIBZ $LIBSOCKET"
+ else
+ LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm $LIBZ $LIBSOCKET"
+ fi
+ CFLAGS="$CFLAGS $X_INCLUDES $USER_INCLUDES"
+ test -n "$XPM_INCLUDE" && CFLAGS="-I$XPM_INCLUDE $CFLAGS"
+ AC_TRY_LINK([#include <X11/xpm.h>],[],
+ ac_cv_have_xpm="yes",ac_cv_have_xpm="no")
+ LDFLAGS="$ac_save_ldflags"
+ CFLAGS="$ac_save_cflags"
+ ])dnl
+
+ if test "$ac_cv_have_xpm" = no; then
+ AC_MSG_RESULT(no)
+ XPM_LDFLAGS=""
+ XPMINC=""
+ $2
+ else
+ AC_DEFINE(HAVE_XPM, 1, [Define if you have XPM support])
+ if test "$XPM_LDFLAGS" = ""; then
+ XPMLIB='-lXpm $(LIB_X11)'
+ else
+ XPMLIB="-L$XPM_LDFLAGS -lXpm "'$(LIB_X11)'
+ fi
+ if test "$XPM_INCLUDE" = ""; then
+ XPMINC=""
+ else
+ XPMINC="-I$XPM_INCLUDE"
+ fi
+ AC_MSG_RESULT(yes)
+ $1
+ fi
+ fi
+ AC_SUBST(XPMINC)
+ AC_SUBST(XPMLIB)
+])
+
+AC_DEFUN([AC_HAVE_DPMS],
+ [AC_REQUIRE_CPP()dnl
+ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+ test -z "$DPMS_LDFLAGS" && DPMS_LDFLAGS=
+ test -z "$DPMS_INCLUDE" && DPMS_INCLUDE=
+ DPMS_LIB=
+
+ AC_ARG_WITH(dpms,AC_HELP_STRING([--without-dpms],[disable DPMS power saving]),
+ dpms_test=$withval, dpms_test="yes")
+ if test "x$dpms_test" = xno; then
+ ac_cv_have_dpms=no
+ else
+ AC_MSG_CHECKING(for DPMS)
+ dnl Note: ac_cv_have_dpms can be no, yes, or -lXdpms.
+ dnl 'yes' means DPMS_LIB="", '-lXdpms' means DPMS_LIB="-lXdpms".
+ AC_CACHE_VAL(ac_cv_have_dpms,
+ [
+ if test "x$kde_use_qt_emb" = "xyes" || test "x$kde_use_qt_mac" = "xyes"; then
+ AC_MSG_RESULT(no)
+ ac_cv_have_dpms="no"
+ else
+ ac_save_ldflags="$LDFLAGS"
+ ac_save_cflags="$CFLAGS"
+ ac_save_libs="$LIBS"
+ LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries"
+ LIBS="-lX11 -lXext $LIBSOCKET"
+ CFLAGS="$CFLAGS $X_INCLUDES"
+ test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS"
+ AC_TRY_LINK([
+ #include <X11/Xproto.h>
+ #include <X11/X.h>
+ #include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>
+ int foo_test_dpms()
+ { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[],
+ ac_cv_have_dpms="yes", [
+ LIBS="-lXdpms $LIBS"
+ AC_TRY_LINK([
+ #include <X11/Xproto.h>
+ #include <X11/X.h>
+ #include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>
+ int foo_test_dpms()
+ { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[],
+ [
+ ac_cv_have_dpms="-lXdpms"
+ ],ac_cv_have_dpms="no")
+ ])
+ LDFLAGS="$ac_save_ldflags"
+ CFLAGS="$ac_save_cflags"
+ LIBS="$ac_save_libs"
+ fi
+ ])dnl
+
+ if test "$ac_cv_have_dpms" = no; then
+ AC_MSG_RESULT(no)
+ DPMS_LDFLAGS=""
+ DPMSINC=""
+ $2
+ else
+ AC_DEFINE(HAVE_DPMS, 1, [Define if you have DPMS support])
+ if test "$ac_cv_have_dpms" = "-lXdpms"; then
+ DPMS_LIB="-lXdpms"
+ fi
+ if test "$DPMS_LDFLAGS" = ""; then
+ DPMSLIB="$DPMS_LIB "'$(LIB_X11)'
+ else
+ DPMSLIB="$DPMS_LDFLAGS $DPMS_LIB "'$(LIB_X11)'
+ fi
+ if test "$DPMS_INCLUDE" = ""; then
+ DPMSINC=""
+ else
+ DPMSINC="-I$DPMS_INCLUDE"
+ fi
+ AC_MSG_RESULT(yes)
+ $1
+ fi
+ fi
+ ac_save_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $X_INCLUDES"
+ test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS"
+ AH_TEMPLATE(HAVE_DPMSCAPABLE_PROTO,
+ [Define if you have the DPMSCapable prototype in <X11/extensions/dpms.h>])
+ AC_CHECK_DECL(DPMSCapable,
+ AC_DEFINE(HAVE_DPMSCAPABLE_PROTO),,
+ [#include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>])
+ AH_TEMPLATE(HAVE_DPMSINFO_PROTO,
+ [Define if you have the DPMSInfo prototype in <X11/extensions/dpms.h>])
+ AC_CHECK_DECL(DPMSInfo,
+ AC_DEFINE(HAVE_DPMSINFO_PROTO),,
+ [#include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>])
+ CFLAGS="$ac_save_cflags"
+ AC_SUBST(DPMSINC)
+ AC_SUBST(DPMSLIB)
+])
+
+AC_DEFUN([AC_HAVE_GL],
+ [AC_REQUIRE_CPP()dnl
+ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+ test -z "$GL_LDFLAGS" && GL_LDFLAGS=
+ test -z "$GL_INCLUDE" && GL_INCLUDE=
+
+ AC_ARG_WITH(gl,AC_HELP_STRING([--without-gl],[disable 3D GL modes]),
+ gl_test=$withval, gl_test="yes")
+ if test "x$kde_use_qt_emb" = "xyes"; then
+ # GL and Qt Embedded is a no-go for now.
+ ac_cv_have_gl=no
+ elif test "x$gl_test" = xno; then
+ ac_cv_have_gl=no
+ else
+ AC_MSG_CHECKING(for GL)
+ AC_CACHE_VAL(ac_cv_have_gl,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_save_ldflags=$LDFLAGS
+ ac_save_cxxflags=$CXXFLAGS
+ ac_save_libs=$LIBS
+ LDFLAGS="$LDFLAGS $GL_LDFLAGS $X_LDFLAGS $all_libraries"
+ LIBS="$LIBS -lGL -lGLU"
+ test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LIBS="$LIBS -lX11"
+ LIBS="$LIBS $LIB_XEXT -lm $LIBSOCKET"
+ CXXFLAGS="$CFLAGS $X_INCLUDES"
+ test -n "$GL_INCLUDE" && CFLAGS="-I$GL_INCLUDE $CFLAGS"
+ AC_TRY_LINK([#include <GL/gl.h>
+#include <GL/glu.h>
+], [],
+ ac_cv_have_gl="yes", ac_cv_have_gl="no")
+ AC_LANG_RESTORE
+ LDFLAGS=$ac_save_ldflags
+ CXXFLAGS=$ac_save_cxxflags
+ LIBS=$ac_save_libs
+ ])dnl
+
+ if test "$ac_cv_have_gl" = "no"; then
+ AC_MSG_RESULT(no)
+ GL_LDFLAGS=""
+ GLINC=""
+ $2
+ else
+ AC_DEFINE(HAVE_GL, 1, [Defines if you have GL (Mesa, OpenGL, ...)])
+ if test "$GL_LDFLAGS" = ""; then
+ GLLIB='-lGLU -lGL $(LIB_X11)'
+ else
+ GLLIB="$GL_LDFLAGS -lGLU -lGL "'$(LIB_X11)'
+ fi
+ if test "$GL_INCLUDE" = ""; then
+ GLINC=""
+ else
+ GLINC="-I$GL_INCLUDE"
+ fi
+ AC_MSG_RESULT($ac_cv_have_gl)
+ $1
+ fi
+ fi
+ AC_SUBST(GLINC)
+ AC_SUBST(GLLIB)
+])
+
+
+ dnl shadow password and PAM magic - maintained by ossi@kde.org
+
+AC_DEFUN([KDE_PAM], [
+ AC_REQUIRE([KDE_CHECK_LIBDL])
+
+ want_pam=
+ AC_ARG_WITH(pam,
+ AC_HELP_STRING([--with-pam[=ARG]],[enable support for PAM: ARG=[yes|no|service name]]),
+ [ if test "x$withval" = "xyes"; then
+ want_pam=yes
+ pam_service=kde
+ elif test "x$withval" = "xno"; then
+ want_pam=no
+ else
+ want_pam=yes
+ pam_service=$withval
+ fi
+ ], [ pam_service=kde ])
+
+ use_pam=
+ PAMLIBS=
+ if test "x$want_pam" != xno; then
+ AC_CHECK_LIB(pam, pam_start, [
+ AC_CHECK_HEADER(security/pam_appl.h,
+ [ pam_header=security/pam_appl.h ],
+ [ AC_CHECK_HEADER(pam/pam_appl.h,
+ [ pam_header=pam/pam_appl.h ],
+ [
+ AC_MSG_WARN([PAM detected, but no headers found!
+Make sure you have the necessary development packages installed.])
+ ]
+ )
+ ]
+ )
+ ], , $LIBDL)
+ if test -z "$pam_header"; then
+ if test "x$want_pam" = xyes; then
+ AC_MSG_ERROR([--with-pam was specified, but cannot compile with PAM!])
+ fi
+ else
+ AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM (Pluggable Authentication Modules)])
+ PAMLIBS="$PAM_MISC_LIB -lpam $LIBDL"
+ use_pam=yes
+
+ dnl darwin claims to be something special
+ if test "$pam_header" = "pam/pam_appl.h"; then
+ AC_DEFINE(HAVE_PAM_PAM_APPL_H, 1, [Define if your PAM headers are in pam/ instead of security/])
+ fi
+
+ dnl test whether struct pam_message is const (Linux) or not (Sun)
+ AC_MSG_CHECKING(for const pam_message)
+ AC_EGREP_HEADER([struct pam_message], $pam_header,
+ [ AC_EGREP_HEADER([const struct pam_message], $pam_header,
+ [AC_MSG_RESULT([const: Linux-type PAM])],
+ [AC_MSG_RESULT([nonconst: Sun-type PAM])
+ AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM support takes non-const arguments (Solaris)])]
+ )],
+ [AC_MSG_RESULT([not found - assume const, Linux-type PAM])])
+ fi
+ fi
+
+ AC_SUBST(PAMLIBS)
+])
+
+dnl DEF_PAM_SERVICE(arg name, full name, define name)
+AC_DEFUN([DEF_PAM_SERVICE], [
+ AC_ARG_WITH($1-pam,
+ AC_HELP_STRING([--with-$1-pam=[val]],[override PAM service from --with-pam for $2]),
+ [ if test "x$use_pam" = xyes; then
+ $3_PAM_SERVICE=$withval
+ else
+ AC_MSG_ERROR([Cannot use use --with-$1-pam, as no PAM was detected.
+You may want to enforce it by using --with-pam.])
+ fi
+ ],
+ [ if test "x$use_pam" = xyes; then
+ $3_PAM_SERVICE="$pam_service"
+ fi
+ ])
+ if test -n "$$3_PAM_SERVICE"; then
+ AC_MSG_RESULT([The PAM service used by $2 will be $$3_PAM_SERVICE])
+ AC_DEFINE_UNQUOTED($3_PAM_SERVICE, "$$3_PAM_SERVICE", [The PAM service to be used by $2])
+ fi
+ AC_SUBST($3_PAM_SERVICE)
+])
+
+AC_DEFUN([KDE_SHADOWPASSWD], [
+ AC_REQUIRE([KDE_PAM])
+
+ AC_CHECK_LIB(shadow, getspent,
+ [ LIBSHADOW="-lshadow"
+ ac_use_shadow=yes
+ ],
+ [ dnl for UnixWare
+ AC_CHECK_LIB(gen, getspent,
+ [ LIBGEN="-lgen"
+ ac_use_shadow=yes
+ ],
+ [ AC_CHECK_FUNC(getspent,
+ [ ac_use_shadow=yes ],
+ [ ac_use_shadow=no ])
+ ])
+ ])
+ AC_SUBST(LIBSHADOW)
+ AC_SUBST(LIBGEN)
+
+ AC_MSG_CHECKING([for shadow passwords])
+
+ AC_ARG_WITH(shadow,
+ AC_HELP_STRING([--with-shadow],[If you want shadow password support]),
+ [ if test "x$withval" != "xno"; then
+ use_shadow=yes
+ else
+ use_shadow=no
+ fi
+ ], [
+ use_shadow="$ac_use_shadow"
+ ])
+
+ if test "x$use_shadow" = xyes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SHADOW, 1, [Define if you use shadow passwords])
+ else
+ AC_MSG_RESULT(no)
+ LIBSHADOW=
+ LIBGEN=
+ fi
+
+ dnl finally make the relevant binaries setuid root, if we have shadow passwds.
+ dnl this still applies, if we could use it indirectly through pam.
+ if test "x$use_shadow" = xyes ||
+ ( test "x$use_pam" = xyes && test "x$ac_use_shadow" = xyes ); then
+ case $host in
+ *-*-freebsd* | *-*-netbsd* | *-*-openbsd*)
+ SETUIDFLAGS="-m 4755 -o root";;
+ *)
+ SETUIDFLAGS="-m 4755";;
+ esac
+ fi
+ AC_SUBST(SETUIDFLAGS)
+
+])
+
+AC_DEFUN([KDE_PASSWDLIBS], [
+ AC_REQUIRE([KDE_MISC_TESTS]) dnl for LIBCRYPT
+ AC_REQUIRE([KDE_PAM])
+ AC_REQUIRE([KDE_SHADOWPASSWD])
+
+ if test "x$use_pam" = "xyes"; then
+ PASSWDLIBS="$PAMLIBS"
+ else
+ PASSWDLIBS="$LIBCRYPT $LIBSHADOW $LIBGEN"
+ fi
+
+ dnl FreeBSD uses a shadow-like setup, where /etc/passwd holds the users, but
+ dnl /etc/master.passwd holds the actual passwords. /etc/master.passwd requires
+ dnl root to read, so kcheckpass needs to be root (even when using pam, since pam
+ dnl may need to read /etc/master.passwd).
+ case $host in
+ *-*-freebsd*)
+ SETUIDFLAGS="-m 4755 -o root"
+ ;;
+ *)
+ ;;
+ esac
+
+ AC_SUBST(PASSWDLIBS)
+])
+
+AC_DEFUN([KDE_CHECK_LIBDL],
+[
+AC_CHECK_LIB(dl, dlopen, [
+LIBDL="-ldl"
+ac_cv_have_dlfcn=yes
+])
+
+AC_CHECK_LIB(dld, shl_unload, [
+LIBDL="-ldld"
+ac_cv_have_shload=yes
+])
+
+AC_SUBST(LIBDL)
+])
+
+AC_DEFUN([KDE_CHECK_DLOPEN],
+[
+KDE_CHECK_LIBDL
+AC_CHECK_HEADERS(dlfcn.h dl.h)
+if test "$ac_cv_header_dlfcn_h" = "no"; then
+ ac_cv_have_dlfcn=no
+fi
+
+if test "$ac_cv_header_dl_h" = "no"; then
+ ac_cv_have_shload=no
+fi
+
+dnl XXX why change enable_dlopen? its already set by autoconf's AC_ARG_ENABLE
+dnl (MM)
+AC_ARG_ENABLE(dlopen,
+AC_HELP_STRING([--disable-dlopen],[link statically [default=no]]),
+enable_dlopen=$enableval,
+enable_dlopen=yes)
+
+# override the user's opinion, if we know it better ;)
+if test "$ac_cv_have_dlfcn" = "no" && test "$ac_cv_have_shload" = "no"; then
+ enable_dlopen=no
+fi
+
+if test "$ac_cv_have_dlfcn" = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_DLFCN, 1, [Define if you have dlfcn])
+fi
+
+if test "$ac_cv_have_shload" = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_SHLOAD, 1, [Define if you have shload])
+fi
+
+if test "$enable_dlopen" = no ; then
+ test -n "$1" && eval $1
+else
+ test -n "$2" && eval $2
+fi
+
+])
+
+AC_DEFUN([KDE_CHECK_DYNAMIC_LOADING],
+[
+KDE_CHECK_DLOPEN(libtool_enable_shared=yes, libtool_enable_static=no)
+KDE_PROG_LIBTOOL
+AC_MSG_CHECKING([dynamic loading])
+eval "`egrep '^build_libtool_libs=' libtool`"
+if test "$build_libtool_libs" = "yes" && test "$enable_dlopen" = "yes"; then
+ dynamic_loading=yes
+ AC_DEFINE_UNQUOTED(HAVE_DYNAMIC_LOADING)
+else
+ dynamic_loading=no
+fi
+AC_MSG_RESULT($dynamic_loading)
+if test "$dynamic_loading" = "yes"; then
+ $1
+else
+ $2
+fi
+])
+
+AC_DEFUN([KDE_ADD_INCLUDES],
+[
+if test -z "$1"; then
+ test_include="Pix.h"
+else
+ test_include="$1"
+fi
+
+AC_MSG_CHECKING([for libg++ ($test_include)])
+
+AC_CACHE_VAL(kde_cv_libgpp_includes,
+[
+kde_cv_libgpp_includes=no
+
+ for ac_dir in \
+ \
+ /usr/include/g++ \
+ /usr/include \
+ /usr/unsupported/include \
+ /opt/include \
+ $extra_include \
+ ; \
+ do
+ if test -r "$ac_dir/$test_include"; then
+ kde_cv_libgpp_includes=$ac_dir
+ break
+ fi
+ done
+])
+
+AC_MSG_RESULT($kde_cv_libgpp_includes)
+if test "$kde_cv_libgpp_includes" != "no"; then
+ all_includes="-I$kde_cv_libgpp_includes $all_includes $USER_INCLUDES"
+fi
+])
+])
+
+AC_DEFUN([KDE_CHECK_LIBPTHREAD],
+[
+ dnl This code is here specifically to handle the
+ dnl various flavors of threading library on FreeBSD
+ dnl 4-, 5-, and 6-, and the (weird) rules around it.
+ dnl There may be an environment PTHREAD_LIBS that
+ dnl specifies what to use; otherwise, search for it.
+ dnl -pthread is special cased and unsets LIBPTHREAD
+ dnl below if found.
+ LIBPTHREAD=""
+
+ if test -n "$PTHREAD_LIBS"; then
+ if test "x$PTHREAD_LIBS" = "x-pthread" ; then
+ LIBPTHREAD="PTHREAD"
+ else
+ PTHREAD_LIBS_save="$PTHREAD_LIBS"
+ PTHREAD_LIBS=`echo "$PTHREAD_LIBS_save" | sed -e 's,^-l,,g'`
+ AC_MSG_CHECKING([for pthread_create in $PTHREAD_LIBS])
+ KDE_CHECK_LIB($PTHREAD_LIBS, pthread_create, [
+ LIBPTHREAD="$PTHREAD_LIBS_save"])
+ PTHREAD_LIBS="$PTHREAD_LIBS_save"
+ fi
+ fi
+
+ dnl Is this test really needed, in the face of the Tru64 test below?
+ if test -z "$LIBPTHREAD"; then
+ AC_CHECK_LIB(pthread, pthread_create, [LIBPTHREAD="-lpthread"])
+ fi
+
+ dnl This is a special Tru64 check, see BR 76171 issue #18.
+ if test -z "$LIBPTHREAD" ; then
+ AC_MSG_CHECKING([for pthread_create in -lpthread])
+ kde_safe_libs=$LIBS
+ LIBS="$LIBS -lpthread"
+ AC_TRY_LINK([#include <pthread.h>],[(void)pthread_create(0,0,0,0);],[
+ AC_MSG_RESULT(yes)
+ LIBPTHREAD="-lpthread"],[
+ AC_MSG_RESULT(no)])
+ LIBS=$kde_safe_libs
+ fi
+
+ dnl Un-special-case for FreeBSD.
+ if test "x$LIBPTHREAD" = "xPTHREAD" ; then
+ LIBPTHREAD=""
+ fi
+
+ AC_SUBST(LIBPTHREAD)
+])
+
+AC_DEFUN([KDE_CHECK_PTHREAD_OPTION],
+[
+ USE_THREADS=""
+ if test -z "$LIBPTHREAD"; then
+ KDE_CHECK_COMPILER_FLAG(pthread, [USE_THREADS="-D_THREAD_SAFE -pthread"])
+ fi
+
+ AH_VERBATIM(__svr_define, [
+#if defined(__SVR4) && !defined(__svr4__)
+#define __svr4__ 1
+#endif
+])
+ case $host_os in
+ solaris*)
+ KDE_CHECK_COMPILER_FLAG(mt, [USE_THREADS="-mt"])
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4"
+ ;;
+ freebsd*)
+ CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE $PTHREAD_CFLAGS"
+ ;;
+ aix*)
+ CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+ LIBPTHREAD="$LIBPTHREAD -lc_r"
+ ;;
+ linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+ if test "$CXX" = "KCC"; then
+ CXXFLAGS="$CXXFLAGS --thread_safe"
+ NOOPT_CXXFLAGS="$NOOPT_CXXFLAGS --thread_safe"
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ AC_SUBST(USE_THREADS)
+ AC_SUBST(LIBPTHREAD)
+])
+
+AC_DEFUN([KDE_CHECK_THREADING],
+[
+ AC_REQUIRE([KDE_CHECK_LIBPTHREAD])
+ AC_REQUIRE([KDE_CHECK_PTHREAD_OPTION])
+ dnl default is yes if libpthread is found and no if no libpthread is available
+ if test -z "$LIBPTHREAD"; then
+ if test -z "$USE_THREADS"; then
+ kde_check_threading_default=no
+ else
+ kde_check_threading_default=yes
+ fi
+ else
+ kde_check_threading_default=yes
+ fi
+ AC_ARG_ENABLE(threading,AC_HELP_STRING([--disable-threading],[disables threading even if libpthread found]),
+ kde_use_threading=$enableval, kde_use_threading=$kde_check_threading_default)
+ if test "x$kde_use_threading" = "xyes"; then
+ AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have a working libpthread (will enable threaded code)])
+ fi
+])
+
+AC_DEFUN([KDE_TRY_LINK_PYTHON],
+[
+if test "$kde_python_link_found" = no; then
+
+if test "$1" = normal; then
+ AC_MSG_CHECKING(if a Python application links)
+else
+ AC_MSG_CHECKING(if Python depends on $2)
+fi
+
+AC_CACHE_VAL(kde_cv_try_link_python_$1,
+[
+kde_save_cflags="$CFLAGS"
+CFLAGS="$CFLAGS $PYTHONINC"
+kde_save_libs="$LIBS"
+LIBS="$LIBS $LIBPYTHON $2 $LIBDL $LIBSOCKET"
+kde_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS $PYTHONLIB"
+
+AC_TRY_LINK(
+[
+#include <Python.h>
+],[
+ PySys_SetArgv(1, 0);
+],
+ [kde_cv_try_link_python_$1=yes],
+ [kde_cv_try_link_python_$1=no]
+)
+CFLAGS="$kde_save_cflags"
+LIBS="$kde_save_libs"
+LDFLAGS="$kde_save_ldflags"
+])
+
+if test "$kde_cv_try_link_python_$1" = "yes"; then
+ AC_MSG_RESULT(yes)
+ kde_python_link_found=yes
+ if test ! "$1" = normal; then
+ LIBPYTHON="$LIBPYTHON $2"
+ fi
+ $3
+else
+ AC_MSG_RESULT(no)
+ $4
+fi
+
+fi
+
+])
+
+AC_DEFUN([KDE_CHECK_PYTHON_DIR],
+[
+AC_MSG_CHECKING([for Python directory])
+
+AC_CACHE_VAL(kde_cv_pythondir,
+[
+ if test -z "$PYTHONDIR"; then
+ kde_cv_pythondir=/usr/local
+ else
+ kde_cv_pythondir="$PYTHONDIR"
+ fi
+])
+
+AC_ARG_WITH(pythondir,
+AC_HELP_STRING([--with-pythondir=pythondir],[use python installed in pythondir]),
+[
+ ac_python_dir=$withval
+], ac_python_dir=$kde_cv_pythondir
+)
+
+AC_MSG_RESULT($ac_python_dir)
+])
+
+AC_DEFUN([KDE_CHECK_PYTHON_INTERN],
+[
+AC_REQUIRE([KDE_CHECK_LIBDL])
+AC_REQUIRE([KDE_CHECK_LIBPTHREAD])
+AC_REQUIRE([KDE_CHECK_PYTHON_DIR])
+
+if test -z "$1"; then
+ version="1.5"
+else
+ version="$1"
+fi
+
+AC_MSG_CHECKING([for Python$version])
+
+python_incdirs="$ac_python_dir/include /usr/include /usr/local/include/ $kde_extra_includes"
+AC_FIND_FILE(Python.h, $python_incdirs, python_incdir)
+if test ! -r $python_incdir/Python.h; then
+ AC_FIND_FILE(python$version/Python.h, $python_incdirs, python_incdir)
+ python_incdir=$python_incdir/python$version
+ if test ! -r $python_incdir/Python.h; then
+ python_incdir=no
+ fi
+fi
+
+PYTHONINC=-I$python_incdir
+
+python_libdirs="$ac_python_dir/lib$kdelibsuff /usr/lib$kdelibsuff /usr/local /usr/lib$kdelibsuff $kde_extra_libs"
+AC_FIND_FILE(libpython$version.so, $python_libdirs, python_libdir)
+if test ! -r $python_libdir/libpython$version.so; then
+ AC_FIND_FILE(libpython$version.a, $python_libdirs, python_libdir)
+ if test ! -r $python_libdir/libpython$version.a; then
+ AC_FIND_FILE(python$version/config/libpython$version.a, $python_libdirs, python_libdir)
+ python_libdir=$python_libdir/python$version/config
+ if test ! -r $python_libdir/libpython$version.a; then
+ python_libdir=no
+ fi
+ fi
+fi
+
+PYTHONLIB=-L$python_libdir
+kde_orig_LIBPYTHON=$LIBPYTHON
+if test -z "$LIBPYTHON"; then
+ LIBPYTHON=-lpython$version
+fi
+
+AC_FIND_FILE(python$version/copy.py, $python_libdirs, python_moddir)
+python_moddir=$python_moddir/python$version
+if test ! -r $python_moddir/copy.py; then
+ python_moddir=no
+fi
+
+PYTHONMODDIR=$python_moddir
+
+AC_MSG_RESULT(header $python_incdir library $python_libdir modules $python_moddir)
+
+if test x$python_incdir = xno || test x$python_libdir = xno || test x$python_moddir = xno; then
+ LIBPYTHON=$kde_orig_LIBPYTHON
+ test "x$PYTHONLIB" = "x-Lno" && PYTHONLIB=""
+ test "x$PYTHONINC" = "x-Ino" && PYTHONINC=""
+ $2
+else
+ dnl Note: this test is very weak
+ kde_python_link_found=no
+ KDE_TRY_LINK_PYTHON(normal)
+ KDE_TRY_LINK_PYTHON(m, -lm)
+ KDE_TRY_LINK_PYTHON(pthread, $LIBPTHREAD)
+ KDE_TRY_LINK_PYTHON(tcl, -ltcl)
+ KDE_TRY_LINK_PYTHON(db2, -ldb2)
+ KDE_TRY_LINK_PYTHON(m_and_thread, [$LIBPTHREAD -lm])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_util, [$LIBPTHREAD -lm -lutil])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_db3, [$LIBPTHREAD -lm -ldb-3 -lutil])
+ KDE_TRY_LINK_PYTHON(pthread_and_db3, [$LIBPTHREAD -ldb-3])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_db, [$LIBPTHREAD -lm -ldb -ltermcap -lutil])
+ KDE_TRY_LINK_PYTHON(pthread_and_dl, [$LIBPTHREAD $LIBDL -lutil -lreadline -lncurses -lm])
+ KDE_TRY_LINK_PYTHON(pthread_and_panel_curses, [$LIBPTHREAD $LIBDL -lm -lpanel -lcurses])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_db_special, [$LIBPTHREAD -lm -ldb -lutil], [],
+ [AC_MSG_WARN([it seems, Python depends on another library.
+ Please set LIBPYTHON to '-lpython$version -lotherlib' before calling configure to fix this
+ and contact the authors to let them know about this problem])
+ ])
+
+ LIBPYTHON="$LIBPYTHON $LIBDL $LIBSOCKET"
+ AC_SUBST(PYTHONINC)
+ AC_SUBST(PYTHONLIB)
+ AC_SUBST(LIBPYTHON)
+ AC_SUBST(PYTHONMODDIR)
+ AC_DEFINE(HAVE_PYTHON, 1, [Define if you have the development files for python])
+fi
+
+])
+
+
+AC_DEFUN([KDE_CHECK_PYTHON],
+[
+ KDE_CHECK_PYTHON_INTERN("2.5",
+ [KDE_CHECK_PYTHON_INTERN("2.4",
+ [KDE_CHECK_PYTHON_INTERN("2.3",
+ [KDE_CHECK_PYTHON_INTERN("2.2",
+ [KDE_CHECK_PYTHON_INTERN("2.1",
+ [KDE_CHECK_PYTHON_INTERN("2.0",
+ [KDE_CHECK_PYTHON_INTERN($1, $2) ])
+ ])
+ ])
+ ])
+ ])
+ ])
+])
+
+AC_DEFUN([KDE_CHECK_STL],
+[
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="`echo $CXXFLAGS | sed s/-fno-exceptions//`"
+
+ AC_MSG_CHECKING([if C++ programs can be compiled])
+ AC_CACHE_VAL(kde_cv_stl_works,
+ [
+ AC_TRY_COMPILE([
+#include <string>
+using namespace std;
+],[
+ string astring="Hallo Welt.";
+ astring.erase(0, 6); // now astring is "Welt"
+ return 0;
+], kde_cv_stl_works=yes,
+ kde_cv_stl_works=no)
+])
+
+ AC_MSG_RESULT($kde_cv_stl_works)
+
+ if test "$kde_cv_stl_works" = "yes"; then
+ # back compatible
+ AC_DEFINE_UNQUOTED(HAVE_SGI_STL, 1, [Define if you have a STL implementation by SGI])
+ else
+ AC_MSG_ERROR([Your Installation isn't able to compile simple C++ programs.
+Check config.log for details - if you're using a Linux distribution you might miss
+a package named similar to libstdc++-dev.])
+ fi
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+
+AC_DEFUN([AC_FIND_QIMGIO],
+ [AC_REQUIRE([AC_FIND_JPEG])
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_MSG_CHECKING([for qimgio])
+AC_CACHE_VAL(ac_cv_lib_qimgio,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ac_save_LIBS="$LIBS"
+ac_save_CXXFLAGS="$CXXFLAGS"
+LIBS="$all_libraries -lqimgio -lpng -lz $LIBJPEG $LIBQT"
+CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes"
+AC_TRY_RUN(dnl
+[
+#include <qimageio.h>
+#include <qstring.h>
+int main() {
+ QString t = "hallo";
+ t.fill('t');
+ qInitImageIO();
+}
+],
+ ac_cv_lib_qimgio=yes,
+ ac_cv_lib_qimgio=no,
+ ac_cv_lib_qimgio=no)
+LIBS="$ac_save_LIBS"
+CXXFLAGS="$ac_save_CXXFLAGS"
+AC_LANG_RESTORE
+])dnl
+if eval "test \"`echo $ac_cv_lib_qimgio`\" = yes"; then
+ LIBQIMGIO="-lqimgio -lpng -lz $LIBJPEG"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_QIMGIO, 1, [Define if you have the Qt extension qimgio available])
+ AC_SUBST(LIBQIMGIO)
+else
+ AC_MSG_RESULT(not found)
+fi
+])
+
+AC_DEFUN([AM_DISABLE_LIBRARIES],
+[
+ AC_PROVIDE([AM_ENABLE_STATIC])
+ AC_PROVIDE([AM_ENABLE_SHARED])
+ enable_static=no
+ enable_shared=yes
+])
+
+
+AC_DEFUN([AC_CHECK_UTMP_FILE],
+[
+ AC_MSG_CHECKING([for utmp file])
+
+ AC_CACHE_VAL(kde_cv_utmp_file,
+ [
+ kde_cv_utmp_file=no
+
+ for ac_file in \
+ \
+ /var/run/utmp \
+ /var/adm/utmp \
+ /etc/utmp \
+ ; \
+ do
+ if test -r "$ac_file"; then
+ kde_cv_utmp_file=$ac_file
+ break
+ fi
+ done
+ ])
+
+ if test "$kde_cv_utmp_file" != "no"; then
+ AC_DEFINE_UNQUOTED(UTMP, "$kde_cv_utmp_file", [Define the file for utmp entries])
+ $1
+ AC_MSG_RESULT($kde_cv_utmp_file)
+ else
+ $2
+ AC_MSG_RESULT([non found])
+ fi
+])
+
+
+AC_DEFUN([KDE_CREATE_SUBDIRSLIST],
+[
+
+DO_NOT_COMPILE="$DO_NOT_COMPILE CVS debian bsd-port admin"
+TOPSUBDIRS=""
+
+if test ! -s $srcdir/subdirs; then
+ dnl Note: Makefile.common creates subdirs, so this is just a fallback
+ files=`cd $srcdir && ls -1`
+ dirs=`for i in $files; do if test -d $i; then echo $i; fi; done`
+ for i in $dirs; do
+ echo $i >> $srcdir/subdirs
+ done
+fi
+
+ac_topsubdirs=
+if test -s $srcdir/inst-apps; then
+ ac_topsubdirs="`cat $srcdir/inst-apps`"
+elif test -s $srcdir/subdirs; then
+ ac_topsubdirs="`cat $srcdir/subdirs`"
+fi
+
+for i in $ac_topsubdirs; do
+ AC_MSG_CHECKING([if $i should be compiled])
+ if test -d $srcdir/$i; then
+ install_it="yes"
+ for j in $DO_NOT_COMPILE; do
+ if test $i = $j; then
+ install_it="no"
+ fi
+ done
+ else
+ install_it="no"
+ fi
+ AC_MSG_RESULT($install_it)
+ vari=`echo $i | sed -e 's,[[-+.@]],_,g'`
+ if test $install_it = "yes"; then
+ TOPSUBDIRS="$TOPSUBDIRS $i"
+ eval "$vari""_SUBDIR_included=yes"
+ else
+ eval "$vari""_SUBDIR_included=no"
+ fi
+done
+
+AC_SUBST(TOPSUBDIRS)
+])
+
+AC_DEFUN([KDE_CHECK_NAMESPACES],
+[
+AC_MSG_CHECKING(whether C++ compiler supports namespaces)
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_TRY_COMPILE([
+],
+[
+namespace Foo {
+ extern int i;
+ namespace Bar {
+ extern int i;
+ }
+}
+
+int Foo::i = 0;
+int Foo::Bar::i = 1;
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NAMESPACES)
+], [
+AC_MSG_RESULT(no)
+])
+AC_LANG_RESTORE
+])
+
+dnl ------------------------------------------------------------------------
+dnl Check for S_ISSOCK macro. Doesn't exist on Unix SCO. faure@kde.org
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_CHECK_S_ISSOCK],
+[
+AC_MSG_CHECKING(for S_ISSOCK)
+AC_CACHE_VAL(ac_cv_have_s_issock,
+[
+AC_TRY_LINK(
+[
+#include <sys/stat.h>
+],
+[
+struct stat buff;
+int b = S_ISSOCK( buff.st_mode );
+],
+ac_cv_have_s_issock=yes,
+ac_cv_have_s_issock=no)
+])
+AC_MSG_RESULT($ac_cv_have_s_issock)
+if test "$ac_cv_have_s_issock" = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_S_ISSOCK, 1, [Define if sys/stat.h declares S_ISSOCK.])
+fi
+
+AH_VERBATIM(_ISSOCK,
+[
+#ifndef HAVE_S_ISSOCK
+#define HAVE_S_ISSOCK
+#define S_ISSOCK(mode) (1==0)
+#endif
+])
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Check for MAXPATHLEN macro, defines KDEMAXPATHLEN. faure@kde.org
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_CHECK_KDEMAXPATHLEN],
+[
+AC_MSG_CHECKING(for MAXPATHLEN)
+AC_CACHE_VAL(ac_cv_maxpathlen,
+[
+cat > conftest.$ac_ext <<EOF
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <sys/param.h>
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+KDE_HELLO MAXPATHLEN
+
+EOF
+
+ac_try="$ac_cpp conftest.$ac_ext 2>/dev/null | grep '^KDE_HELLO' >conftest.out"
+
+if AC_TRY_EVAL(ac_try) && test -s conftest.out; then
+ ac_cv_maxpathlen=`sed 's#KDE_HELLO ##' conftest.out`
+else
+ ac_cv_maxpathlen=1024
+fi
+
+rm conftest.*
+
+])
+AC_MSG_RESULT($ac_cv_maxpathlen)
+AC_DEFINE_UNQUOTED(KDEMAXPATHLEN,$ac_cv_maxpathlen, [Define a safe value for MAXPATHLEN] )
+])
+
+AC_DEFUN([KDE_CHECK_HEADER],
+[
+ kde_safe_cppflags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $all_includes"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_CHECK_HEADER([$1], [$2], [$3], [$4])
+ AC_LANG_RESTORE
+ CPPFLAGS=$kde_safe_cppflags
+])
+
+AC_DEFUN([KDE_CHECK_HEADERS],
+[
+ AH_CHECK_HEADERS([$1])
+ AC_LANG_SAVE
+ kde_safe_cppflags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $all_includes"
+ AC_LANG_CPLUSPLUS
+ AC_CHECK_HEADERS([$1], [$2], [$3], [$4])
+ CPPFLAGS=$kde_safe_cppflags
+ AC_LANG_RESTORE
+])
+
+AC_DEFUN([KDE_FAST_CONFIGURE],
+[
+ dnl makes configure fast (needs perl)
+ AC_ARG_ENABLE(fast-perl, AC_HELP_STRING([--disable-fast-perl],[disable fast Makefile generation (needs perl)]),
+ with_fast_perl=$enableval, with_fast_perl=yes)
+])
+
+AC_DEFUN([KDE_CONF_FILES],
+[
+ val=
+ if test -f $srcdir/configure.files ; then
+ val=`sed -e 's%^%\$(top_srcdir)/%' $srcdir/configure.files`
+ fi
+ CONF_FILES=
+ if test -n "$val" ; then
+ for i in $val ; do
+ CONF_FILES="$CONF_FILES $i"
+ done
+ fi
+ AC_SUBST(CONF_FILES)
+])dnl
+
+dnl This sets the prefix, for arts and kdelibs
+dnl Do NOT use in any other module.
+dnl It only looks at --prefix, KDEDIR and falls back to /usr/local/kde
+AC_DEFUN([KDE_SET_PREFIX_CORE],
+[
+ unset CDPATH
+ dnl make $KDEDIR the default for the installation
+ AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde})
+
+ if test "x$prefix" = "xNONE"; then
+ prefix=$ac_default_prefix
+ ac_configure_args="$ac_configure_args --prefix=$prefix"
+ fi
+ # And delete superfluous '/' to make compares easier
+ prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+ exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+
+ kde_libs_prefix='$(prefix)'
+ kde_libs_htmldir='$(kde_htmldir)'
+ AC_SUBST(kde_libs_prefix)
+ AC_SUBST(kde_libs_htmldir)
+ KDE_FAST_CONFIGURE
+ KDE_CONF_FILES
+])
+
+
+AC_DEFUN([KDE_SET_PREFIX],
+[
+ unset CDPATH
+ dnl We can't give real code to that macro, only a value.
+ dnl It only matters for --help, since we set the prefix in this function anyway.
+ AC_PREFIX_DEFAULT(${KDEDIR:-the kde prefix})
+
+ KDE_SET_DEFAULT_BINDIRS
+ if test "x$prefix" = "xNONE"; then
+ dnl no prefix given: look for kde-config in the PATH and deduce the prefix from it
+ KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend)
+ else
+ dnl prefix given: look for kde-config, preferrably in prefix, otherwise in PATH
+ kde_save_PATH="$PATH"
+ PATH="$exec_prefix/bin:$prefix/bin:$PATH"
+ KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend)
+ PATH="$kde_save_PATH"
+ fi
+
+ kde_libs_prefix=`$KDECONFIG --prefix`
+ if test -z "$kde_libs_prefix" || test ! -x "$kde_libs_prefix"; then
+ AC_MSG_ERROR([$KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs.
+ This means it has been moved since you installed it.
+ This won't work. Please recompile kdelibs for the new prefix.
+ ])
+ fi
+ kde_libs_htmldir=`$KDECONFIG --install html --expandvars`
+
+ AC_MSG_CHECKING([where to install])
+ if test "x$prefix" = "xNONE"; then
+ prefix=$kde_libs_prefix
+ AC_MSG_RESULT([$prefix (as returned by kde-config)])
+ else
+ dnl --prefix was given. Compare prefixes and warn (in configure.in.bot.end) if different
+ given_prefix=$prefix
+ AC_MSG_RESULT([$prefix (as requested)])
+ fi
+
+ # And delete superfluous '/' to make compares easier
+ prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+ exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+ given_prefix=`echo "$given_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+
+ AC_SUBST(KDECONFIG)
+ AC_SUBST(kde_libs_prefix)
+ AC_SUBST(kde_libs_htmldir)
+
+ KDE_FAST_CONFIGURE
+ KDE_CONF_FILES
+])
+
+pushdef([AC_PROG_INSTALL],
+[
+ dnl our own version, testing for a -p flag
+ popdef([AC_PROG_INSTALL])
+ dnl as AC_PROG_INSTALL works as it works we first have
+ dnl to save if the user didn't specify INSTALL, as the
+ dnl autoconf one overwrites INSTALL and we have no chance to find
+ dnl out afterwards
+ test -n "$INSTALL" && kde_save_INSTALL_given=$INSTALL
+ test -n "$INSTALL_PROGRAM" && kde_save_INSTALL_PROGRAM_given=$INSTALL_PROGRAM
+ test -n "$INSTALL_SCRIPT" && kde_save_INSTALL_SCRIPT_given=$INSTALL_SCRIPT
+ AC_PROG_INSTALL
+
+ if test -z "$kde_save_INSTALL_given" ; then
+ # OK, user hasn't given any INSTALL, autoconf found one for us
+ # now we test, if it supports the -p flag
+ AC_MSG_CHECKING(for -p flag to install)
+ rm -f confinst.$$.* > /dev/null 2>&1
+ echo "Testtest" > confinst.$$.orig
+ ac_res=no
+ if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
+ if test -f confinst.$$.new ; then
+ # OK, -p seems to do no harm to install
+ INSTALL="${INSTALL} -p"
+ ac_res=yes
+ fi
+ fi
+ rm -f confinst.$$.*
+ AC_MSG_RESULT($ac_res)
+ fi
+ dnl the following tries to resolve some signs and wonders coming up
+ dnl with different autoconf/automake versions
+ dnl e.g.:
+ dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
+ dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
+ dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
+ dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
+ dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
+ dnl install-@DIR@PROGRAMS targets to explicitly use that flag
+ dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
+ dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
+ dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
+ dnl *sometimes KDE does not use the install-@DIR@PROGRAM targets from
+ dnl automake (due to broken Makefile.am or whatever) to install programs,
+ dnl and so does not see the -s flag in automake > 1.4
+ dnl to clean up that mess we:
+ dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
+ dnl which cleans KDE's program with automake > 1.4;
+ dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
+ dnl with automake<=1.4
+ dnl note that dues to this sometimes two '-s' flags are used (if KDE
+ dnl properly uses install-@DIR@PROGRAMS, but I don't care
+ dnl
+ dnl And to all this comes, that I even can't write in comments variable
+ dnl names used by automake, because it is so stupid to think I wanted to
+ dnl _use_ them, therefor I have written A_M_... instead of AM_
+ dnl hmm, I wanted to say something ... ahh yes: Arghhh.
+
+ if test -z "$kde_save_INSTALL_PROGRAM_given" ; then
+ INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
+ fi
+ if test -z "$kde_save_INSTALL_SCRIPT_given" ; then
+ INSTALL_SCRIPT='${INSTALL}'
+ fi
+])dnl
+
+AC_DEFUN([KDE_LANG_CPLUSPLUS],
+[AC_LANG_CPLUSPLUS
+ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&AC_FD_CC'
+pushdef([AC_LANG_CPLUSPLUS], [popdef([AC_LANG_CPLUSPLUS]) KDE_LANG_CPLUSPLUS])
+])
+
+pushdef([AC_LANG_CPLUSPLUS],
+[popdef([AC_LANG_CPLUSPLUS])
+KDE_LANG_CPLUSPLUS
+])
+
+AC_DEFUN([KDE_CHECK_LONG_LONG],
+[
+AC_MSG_CHECKING(for long long)
+AC_CACHE_VAL(kde_cv_c_long_long,
+[
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_LINK([], [
+ long long foo = 0;
+ foo = foo+1;
+ ],
+ kde_cv_c_long_long=yes, kde_cv_c_long_long=no)
+ AC_LANG_RESTORE
+])
+AC_MSG_RESULT($kde_cv_c_long_long)
+if test "$kde_cv_c_long_long" = yes; then
+ AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have long long as datatype])
+fi
+])
+
+AC_DEFUN([KDE_CHECK_LIB],
+[
+ kde_save_LDFLAGS="$LDFLAGS"
+ dnl AC_CHECK_LIB modifies LIBS, so save it here
+ kde_save_LIBS="$LIBS"
+ LDFLAGS="$LDFLAGS $all_libraries"
+ case $host_os in
+ aix*) LDFLAGS="-brtl $LDFLAGS"
+ test "$GCC" = yes && LDFLAGS="-Wl,$LDFLAGS"
+ ;;
+ esac
+ AC_CHECK_LIB($1, $2, $3, $4, $5)
+ LDFLAGS="$kde_save_LDFLAGS"
+ LIBS="$kde_save_LIBS"
+])
+
+AC_DEFUN([KDE_JAVA_PREFIX],
+[
+ dir=`dirname "$1"`
+ base=`basename "$1"`
+ list=`ls -1 $dir 2> /dev/null`
+ for entry in $list; do
+ if test -d $dir/$entry/bin; then
+ case $entry in
+ $base)
+ javadirs="$javadirs $dir/$entry/bin"
+ ;;
+ esac
+ elif test -d $dir/$entry/jre/bin; then
+ case $entry in
+ $base)
+ javadirs="$javadirs $dir/$entry/jre/bin"
+ ;;
+ esac
+ fi
+ done
+])
+
+dnl KDE_CHEC_JAVA_DIR(onlyjre)
+AC_DEFUN([KDE_CHECK_JAVA_DIR],
+[
+
+AC_ARG_WITH(java,
+AC_HELP_STRING([--with-java=javadir],[use java installed in javadir, --without-java disables]),
+[ ac_java_dir=$withval
+], ac_java_dir=""
+)
+
+AC_MSG_CHECKING([for Java])
+
+dnl at this point ac_java_dir is either a dir, 'no' to disable, or '' to say look in $PATH
+if test "x$ac_java_dir" = "xno"; then
+ kde_java_bindir=no
+ kde_java_includedir=no
+ kde_java_libjvmdir=no
+ kde_java_libgcjdir=no
+ kde_java_libhpidir=no
+else
+ if test "x$ac_java_dir" = "x"; then
+
+
+ dnl No option set -> collect list of candidate paths
+ if test -n "$JAVA_HOME"; then
+ KDE_JAVA_PREFIX($JAVA_HOME)
+ fi
+ KDE_JAVA_PREFIX(/usr/j2se)
+ KDE_JAVA_PREFIX(/usr/lib/j2se)
+ KDE_JAVA_PREFIX(/usr/j*dk*)
+ KDE_JAVA_PREFIX(/usr/lib/j*dk*)
+ KDE_JAVA_PREFIX(/opt/j*sdk*)
+ KDE_JAVA_PREFIX(/usr/lib/java*)
+ KDE_JAVA_PREFIX(/usr/java*)
+ KDE_JAVA_PREFIX(/usr/java/j*dk*)
+ KDE_JAVA_PREFIX(/usr/java/j*re*)
+ KDE_JAVA_PREFIX(/usr/lib/SunJava2*)
+ KDE_JAVA_PREFIX(/usr/lib/SunJava*)
+ KDE_JAVA_PREFIX(/usr/lib/IBMJava2*)
+ KDE_JAVA_PREFIX(/usr/lib/IBMJava*)
+ KDE_JAVA_PREFIX(/opt/java*)
+
+ kde_cv_path="NONE"
+ kde_save_IFS=$IFS
+ IFS=':'
+ for dir in $PATH; do
+ if test -d "$dir"; then
+ javadirs="$javadirs $dir"
+ fi
+ done
+ IFS=$kde_save_IFS
+ jredirs=
+
+ dnl Now javadirs contains a list of paths that exist, all ending with bin/
+ for dir in $javadirs; do
+ dnl Check for the java executable
+ if test -x "$dir/java"; then
+ sane_path=$(cd $dir; /bin/pwd)
+ dnl And also check for a libjvm.so somewhere under there
+ dnl Since we have to go to the parent dir, /usr/bin is excluded, /usr is too big.
+ if test "$sane_path" != "/usr/bin"; then
+ libjvmdir=`find $dir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1`
+ if test ! -f $libjvmdir/libjvm.so; then continue; fi
+ jredirs="$jredirs $dir"
+ fi
+ fi
+ done
+
+ dnl Now jredirs contains a reduced list, of paths where both java and ../**/libjvm.so was found
+ JAVAC=
+ JAVA=
+ kde_java_bindir=no
+ for dir in $jredirs; do
+ JAVA="$dir/java"
+ kde_java_bindir=$dir
+ if test -x "$dir/javac"; then
+ JAVAC="$dir/javac"
+ break
+ fi
+ done
+
+ if test -n "$JAVAC"; then
+ dnl this substitution might not work - well, we test for jni.h below
+ kde_java_includedir=`echo $JAVAC | sed -e 's,bin/javac$,include/,'`
+ else
+ kde_java_includedir=no
+ fi
+ else
+ dnl config option set
+ kde_java_bindir=$ac_java_dir/bin
+ if test -x $ac_java_dir/bin/java && test ! -x $ac_java_dir/bin/javac; then
+ kde_java_includedir=no
+ else
+ kde_java_includedir=$ac_java_dir/include
+ fi
+ fi
+fi
+
+dnl At this point kde_java_bindir and kde_java_includedir are either set or "no"
+if test "x$kde_java_bindir" != "xno"; then
+
+ dnl Look for libjvm.so
+ kde_java_libjvmdir=`find $kde_java_bindir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1`
+ dnl Look for libgcj.so
+ kde_java_libgcjdir=`find $kde_java_bindir/.. -name libgcj.so | sed 's,libgcj.so,,'|head -n 1`
+ dnl Look for libhpi.so and avoid green threads
+ kde_java_libhpidir=`find $kde_java_bindir/.. -name libhpi.so | grep -v green | sed 's,libhpi.so,,' | head -n 1`
+
+ dnl Now check everything's fine under there
+ dnl the include dir is our flag for having the JDK
+ if test -d "$kde_java_includedir"; then
+ if test ! -x "$kde_java_bindir/javac"; then
+ AC_MSG_ERROR([javac not found under $kde_java_bindir - it seems you passed a wrong --with-java.])
+ fi
+ if test ! -x "$kde_java_bindir/javah"; then
+ AC_MSG_ERROR([javah not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.])
+ fi
+ if test ! -x "$kde_java_bindir/jar"; then
+ AC_MSG_ERROR([jar not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.])
+ fi
+ if test ! -r "$kde_java_includedir/jni.h"; then
+ AC_MSG_ERROR([jni.h not found under $kde_java_includedir. Use --with-java or --without-java.])
+ fi
+
+ jni_includes="-I$kde_java_includedir"
+ dnl Strange thing, jni.h requires jni_md.h which is under genunix here..
+ dnl and under linux here..
+
+ dnl not needed for gcj
+
+ if test "x$kde_java_libgcjdir" = "x"; then
+ test -d "$kde_java_includedir/linux" && jni_includes="$jni_includes -I$kde_java_includedir/linux"
+ test -d "$kde_java_includedir/solaris" && jni_includes="$jni_includes -I$kde_java_includedir/solaris"
+ test -d "$kde_java_includedir/genunix" && jni_includes="$jni_includes -I$kde_java_includedir/genunix"
+ fi
+
+ else
+ JAVAC=
+ jni_includes=
+ fi
+
+ if test "x$kde_java_libgcjdir" = "x"; then
+ if test ! -r "$kde_java_libjvmdir/libjvm.so"; then
+ AC_MSG_ERROR([libjvm.so not found under $kde_java_libjvmdir. Use --without-java.])
+ fi
+ else
+ if test ! -r "$kde_java_libgcjdir/libgcj.so"; then
+ AC_MSG_ERROR([libgcj.so not found under $kde_java_libgcjdir. Use --without-java.])
+ fi
+ fi
+
+ if test ! -x "$kde_java_bindir/java"; then
+ AC_MSG_ERROR([java not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.])
+ fi
+
+ dnl not needed for gcj compile
+
+ if test "x$kde_java_libgcjdir" = "x"; then
+ if test ! -r "$kde_java_libhpidir/libhpi.so"; then
+ AC_MSG_ERROR([libhpi.so not found under $kde_java_libhpidir. Use --without-java.])
+ fi
+ fi
+
+ if test -n "$jni_includes"; then
+ dnl Check for JNI version
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_cxxflags_safe="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $all_includes $jni_includes"
+
+ AC_TRY_COMPILE([
+ #include <jni.h>
+ ],
+ [
+ #ifndef JNI_VERSION_1_2
+ Syntax Error
+ #endif
+ ],[ kde_jni_works=yes ],
+ [ kde_jni_works=no ])
+
+ if test $kde_jni_works = no; then
+ AC_MSG_ERROR([Incorrect version of $kde_java_includedir/jni.h.
+ You need to have Java Development Kit (JDK) version 1.2.
+
+ Use --with-java to specify another location.
+ Use --without-java to configure without java support.
+ Or download a newer JDK and try again.
+ See e.g. http://java.sun.com/products/jdk/1.2 ])
+ fi
+
+ CXXFLAGS="$ac_cxxflags_safe"
+ AC_LANG_RESTORE
+
+ dnl All tests ok, inform and subst the variables
+
+ JAVAC=$kde_java_bindir/javac
+ JAVAH=$kde_java_bindir/javah
+ JAR=$kde_java_bindir/jar
+ AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is])
+ if test "x$kde_java_libgcjdir" = "x"; then
+ JVMLIBS="-L$kde_java_libjvmdir -ljvm -L$kde_java_libhpidir -lhpi"
+ else
+ JVMLIBS="-L$kde_java_libgcjdir -lgcj"
+ fi
+ AC_MSG_RESULT([java JDK in $kde_java_bindir])
+
+ else
+ AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is])
+ AC_MSG_RESULT([java JRE in $kde_java_bindir])
+ fi
+elif test -d "/Library/Java/Home"; then
+ kde_java_bindir="/Library/Java/Home/bin"
+ jni_includes="-I/Library/Java/Home/include"
+
+ JAVAC=$kde_java_bindir/javac
+ JAVAH=$kde_java_bindir/javah
+ JAR=$kde_java_bindir/jar
+ JVMLIBS="-Wl,-framework,JavaVM"
+
+ AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is])
+ AC_MSG_RESULT([Apple Java Framework])
+else
+ AC_MSG_RESULT([none found])
+fi
+
+AC_SUBST(JAVAC)
+AC_SUBST(JAVAH)
+AC_SUBST(JAR)
+AC_SUBST(JVMLIBS)
+AC_SUBST(jni_includes)
+
+# for backward compat
+kde_cv_java_includedir=$kde_java_includedir
+kde_cv_java_bindir=$kde_java_bindir
+])
+
+dnl this is a redefinition of autoconf 2.5x's AC_FOREACH.
+dnl When the argument list becomes big, as in KDE for AC_OUTPUT in
+dnl big packages, m4_foreach is dog-slow. So use our own version of
+dnl it. (matz@kde.org)
+m4_define([mm_foreach],
+[m4_pushdef([$1])_mm_foreach($@)m4_popdef([$1])])
+m4_define([mm_car], [[$1]])
+m4_define([mm_car2], [[$@]])
+m4_define([_mm_foreach],
+[m4_if(m4_quote($2), [], [],
+ [m4_define([$1], mm_car($2))$3[]_mm_foreach([$1],
+ mm_car2(m4_shift($2)),
+ [$3])])])
+m4_define([AC_FOREACH],
+[mm_foreach([$1], m4_split(m4_normalize([$2])), [$3])])
+
+AC_DEFUN([KDE_NEED_FLEX],
+[
+kde_libs_safe=$LIBS
+LIBS="$LIBS $USER_LDFLAGS"
+AM_PROG_LEX
+LIBS=$kde_libs_safe
+if test -z "$LEXLIB"; then
+ AC_MSG_ERROR([You need to have flex installed.])
+fi
+AC_SUBST(LEXLIB)
+])
+
+AC_DEFUN([AC_PATH_QTOPIA],
+[
+ dnl TODO: use AC_CACHE_VAL
+
+ if test -z "$1"; then
+ qtopia_minver_maj=1
+ qtopia_minver_min=5
+ qtopia_minver_pat=0
+ else
+ qtopia_minver_maj=`echo "$1" | sed -e "s/^\(.*\)\..*\..*$/\1/"`
+ qtopia_minver_min=`echo "$1" | sed -e "s/^.*\.\(.*\)\..*$/\1/"`
+ qtopia_minver_pat=`echo "$1" | sed -e "s/^.*\..*\.\(.*\)$/\1/"`
+ fi
+
+ qtopia_minver="$qtopia_minver_maj$qtopia_minver_min$qtopia_minver_pat"
+ qtopia_minverstr="$qtopia_minver_maj.$qtopia_minver_min.$qtopia_minver_pat"
+
+ AC_REQUIRE([AC_PATH_QT])
+
+ AC_MSG_CHECKING([for Qtopia])
+
+ LIB_QTOPIA="-lqpe"
+ AC_SUBST(LIB_QTOPIA)
+
+ kde_qtopia_dirs="$QPEDIR /opt/Qtopia"
+
+ ac_qtopia_incdir=NO
+
+ AC_ARG_WITH(qtopia-dir,
+ AC_HELP_STRING([--with-qtopia-dir=DIR],[where the root of Qtopia is installed]),
+ [ ac_qtopia_incdir="$withval"/include] )
+
+ qtopia_incdirs=""
+ for dir in $kde_qtopia_dirs; do
+ qtopia_incdirs="$qtopia_incdirs $dir/include"
+ done
+
+ if test ! "$ac_qtopia_incdir" = "NO"; then
+ qtopia_incdirs="$ac_qtopia_incdir $qtopia_incdirs"
+ fi
+
+ qtopia_incdir=""
+ AC_FIND_FILE(qpe/qpeapplication.h, $qtopia_incdirs, qtopia_incdir)
+ ac_qtopia_incdir="$qtopia_incdir"
+
+ if test -z "$qtopia_incdir"; then
+ AC_MSG_ERROR([Cannot find Qtopia headers. Please check your installation.])
+ fi
+
+ qtopia_ver_maj=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION "\(.*\)\..*\..*".*,\1,p'`;
+ qtopia_ver_min=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\.\(.*\)\..*".*,\1,p'`;
+ qtopia_ver_pat=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\..*\.\(.*\)".*,\1,p'`;
+
+ qtopia_ver="$qtopia_ver_maj$qtopia_ver_min$qtopia_ver_pat"
+ qtopia_verstr="$qtopia_ver_maj.$qtopia_ver_min.$qtopia_ver_pat"
+ if test "$qtopia_ver" -lt "$qtopia_minver"; then
+ AC_MSG_ERROR([found Qtopia version $qtopia_verstr but version $qtopia_minverstr
+is required.])
+ fi
+
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ ac_cxxflags_safe="$CXXFLAGS"
+ ac_ldflags_safe="$LDFLAGS"
+ ac_libs_safe="$LIBS"
+
+ CXXFLAGS="$CXXFLAGS -I$qtopia_incdir $all_includes"
+ LDFLAGS="$LDFLAGS $QT_LDFLAGS $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS"
+ LIBS="$LIBS $LIB_QTOPIA $LIBQT"
+
+ cat > conftest.$ac_ext <<EOF
+#include "confdefs.h"
+#include <qpe/qpeapplication.h>
+#include <qpe/version.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication app( argc, argv );
+ return 0;
+}
+EOF
+
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ rm -f conftest*
+ else
+ rm -f conftest*
+ AC_MSG_ERROR([Cannot link small Qtopia Application. For more details look at
+the end of config.log])
+ fi
+
+ CXXFLAGS="$ac_cxxflags_safe"
+ LDFLAGS="$ac_ldflags_safe"
+ LIBS="$ac_libs_safe"
+
+ AC_LANG_RESTORE
+
+ QTOPIA_INCLUDES="-I$qtopia_incdir"
+ AC_SUBST(QTOPIA_INCLUDES)
+
+ AC_MSG_RESULT([found version $qtopia_verstr with headers at $qtopia_incdir])
+])
+
+
+AC_DEFUN([KDE_INIT_DOXYGEN],
+[
+AC_MSG_CHECKING([for Qt docs])
+kde_qtdir=
+if test "${with_qt_dir+set}" = set; then
+ kde_qtdir="$with_qt_dir"
+fi
+
+AC_FIND_FILE(qsql.html, [ $kde_qtdir/doc/html $QTDIR/doc/html /usr/share/doc/packages/qt3/html /usr/lib/qt/doc /usr/lib/qt3/doc /usr/lib/qt3/doc/html /usr/doc/qt3/html /usr/doc/qt3 /usr/share/doc/qt3-doc /usr/share/qt3/doc/html /usr/X11R6/share/doc/qt/html ], QTDOCDIR)
+AC_MSG_RESULT($QTDOCDIR)
+
+AC_SUBST(QTDOCDIR)
+
+KDE_FIND_PATH(dot, DOT, [], [])
+if test -n "$DOT"; then
+ KDE_HAVE_DOT="YES"
+else
+ KDE_HAVE_DOT="NO"
+fi
+AC_SUBST(KDE_HAVE_DOT)
+KDE_FIND_PATH(doxygen, DOXYGEN, [], [])
+AC_SUBST(DOXYGEN)
+
+DOXYGEN_PROJECT_NAME="$1"
+DOXYGEN_PROJECT_NUMBER="$2"
+AC_SUBST(DOXYGEN_PROJECT_NAME)
+AC_SUBST(DOXYGEN_PROJECT_NUMBER)
+
+KDE_HAS_DOXYGEN=no
+if test -n "$DOXYGEN" && test -x "$DOXYGEN" && test -f $QTDOCDIR/qsql.html; then
+ KDE_HAS_DOXYGEN=yes
+fi
+AC_SUBST(KDE_HAS_DOXYGEN)
+
+])
+
+
+AC_DEFUN([AC_FIND_BZIP2],
+[
+AC_MSG_CHECKING([for bzDecompress in libbz2])
+AC_CACHE_VAL(ac_cv_lib_bzip2,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+kde_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS -lbz2 $LIBSOCKET"
+kde_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(dnl
+[
+#define BZ_NO_STDIO
+#include<bzlib.h>
+],
+ [ bz_stream s; (void) bzDecompress(&s); ],
+ eval "ac_cv_lib_bzip2='-lbz2'",
+ eval "ac_cv_lib_bzip2=no")
+LIBS="$kde_save_LIBS"
+CXXFLAGS="$kde_save_CXXFLAGS"
+AC_LANG_RESTORE
+])dnl
+AC_MSG_RESULT($ac_cv_lib_bzip2)
+
+if test ! "$ac_cv_lib_bzip2" = no; then
+ BZIP2DIR=bzip2
+
+ LIBBZ2="$ac_cv_lib_bzip2"
+ AC_SUBST(LIBBZ2)
+
+else
+
+ cxx_shared_flag=
+ ld_shared_flag=
+ KDE_CHECK_COMPILER_FLAG(shared, [
+ ld_shared_flag="-shared"
+ ])
+ KDE_CHECK_COMPILER_FLAG(fPIC, [
+ cxx_shared_flag="-fPIC"
+ ])
+
+ AC_MSG_CHECKING([for BZ2_bzDecompress in (shared) libbz2])
+ AC_CACHE_VAL(ac_cv_lib_bzip2_prefix,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ kde_save_LIBS="$LIBS"
+ LIBS="$all_libraries $USER_LDFLAGS $ld_shared_flag -lbz2 $LIBSOCKET"
+ kde_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CFLAGS $cxx_shared_flag $all_includes $USER_INCLUDES"
+
+ AC_TRY_LINK(dnl
+ [
+ #define BZ_NO_STDIO
+ #include<bzlib.h>
+ ],
+ [ bz_stream s; (void) BZ2_bzDecompress(&s); ],
+ eval "ac_cv_lib_bzip2_prefix='-lbz2'",
+ eval "ac_cv_lib_bzip2_prefix=no")
+ LIBS="$kde_save_LIBS"
+ CXXFLAGS="$kde_save_CXXFLAGS"
+ AC_LANG_RESTORE
+ ])dnl
+
+ AC_MSG_RESULT($ac_cv_lib_bzip2_prefix)
+
+ if test ! "$ac_cv_lib_bzip2_prefix" = no; then
+ BZIP2DIR=bzip2
+
+ LIBBZ2="$ac_cv_lib_bzip2_prefix"
+ AC_SUBST(LIBBZ2)
+
+ AC_DEFINE(NEED_BZ2_PREFIX, 1, [Define if the libbz2 functions need the BZ2_ prefix])
+ dnl else, we just ignore this
+ fi
+
+fi
+AM_CONDITIONAL(include_BZIP2, test -n "$BZIP2DIR")
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the SSL headers and libraries.
+dnl $(SSL_LDFLAGS) will be -Lsslliblocation (if needed)
+dnl and $(SSL_INCLUDES) will be -Isslhdrlocation (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([KDE_CHECK_SSL],
+[
+LIBSSL="-lssl -lcrypto"
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+ac_ssl_includes=NO ac_ssl_libraries=NO
+ssl_libraries=""
+ssl_includes=""
+AC_ARG_WITH(ssl-dir,
+ AC_HELP_STRING([--with-ssl-dir=DIR],[where the root of OpenSSL is installed]),
+ [ ac_ssl_includes="$withval"/include
+ ac_ssl_libraries="$withval"/lib$kdelibsuff
+ ])
+
+want_ssl=yes
+AC_ARG_WITH(ssl,
+ AC_HELP_STRING([--without-ssl],[disable SSL checks]),
+ [want_ssl=$withval])
+
+if test $want_ssl = yes; then
+
+AC_MSG_CHECKING(for OpenSSL)
+
+AC_CACHE_VAL(ac_cv_have_ssl,
+[#try to guess OpenSSL locations
+
+ ssl_incdirs="/usr/include /usr/local/include /usr/ssl/include /usr/local/ssl/include $prefix/include $kde_extra_includes"
+ ssl_incdirs="$ac_ssl_includes $ssl_incdirs"
+ AC_FIND_FILE(openssl/ssl.h, $ssl_incdirs, ssl_incdir)
+ ac_ssl_includes="$ssl_incdir"
+
+ ssl_libdirs="/usr/lib$kdelibsuff /usr/local/lib$kdelibsuff /usr/ssl/lib$kdelibsuff /usr/local/ssl/lib$kdelibsuff $libdir $prefix/lib$kdelibsuff $exec_prefix/lib$kdelibsuff $kde_extra_libs"
+ if test ! "$ac_ssl_libraries" = "NO"; then
+ ssl_libdirs="$ac_ssl_libraries $ssl_libdirs"
+ fi
+
+ test=NONE
+ ssl_libdir=NONE
+ for dir in $ssl_libdirs; do
+ try="ls -1 $dir/libssl*"
+ if test=`eval $try 2> /dev/null`; then ssl_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi
+ done
+
+ ac_ssl_libraries="$ssl_libdir"
+
+ ac_ldflags_safe="$LDFLAGS"
+ ac_libs_safe="$LIBS"
+
+ LDFLAGS="$LDFLAGS -L$ssl_libdir $all_libraries"
+ LIBS="$LIBS $LIBSSL -lRSAglue -lrsaref"
+
+ AC_TRY_LINK(,void RSAPrivateEncrypt(void);RSAPrivateEncrypt();,
+ ac_ssl_rsaref="yes"
+ ,
+ ac_ssl_rsaref="no"
+ )
+
+ LDFLAGS="$ac_ldflags_safe"
+ LIBS="$ac_libs_safe"
+
+ if test "$ac_ssl_includes" = NO || test "$ac_ssl_libraries" = NO; then
+ have_ssl=no
+ else
+ have_ssl=yes;
+ fi
+
+ ])
+
+ eval "$ac_cv_have_ssl"
+
+ AC_MSG_RESULT([libraries $ac_ssl_libraries, headers $ac_ssl_includes])
+
+ AC_MSG_CHECKING([whether OpenSSL uses rsaref])
+ AC_MSG_RESULT($ac_ssl_rsaref)
+
+ AC_MSG_CHECKING([for easter eggs])
+ AC_MSG_RESULT([none found])
+
+else
+ have_ssl=no
+fi
+
+if test "$have_ssl" = yes; then
+ AC_MSG_CHECKING(for OpenSSL version)
+ dnl Check for SSL version
+ AC_CACHE_VAL(ac_cv_ssl_version,
+ [
+
+ cat >conftest.$ac_ext <<EOF
+#include <openssl/opensslv.h>
+#include <stdio.h>
+ int main() {
+
+#ifndef OPENSSL_VERSION_NUMBER
+ printf("ssl_version=\\"error\\"\n");
+#else
+ if (OPENSSL_VERSION_NUMBER < 0x00906000)
+ printf("ssl_version=\\"old\\"\n");
+ else
+ printf("ssl_version=\\"ok\\"\n");
+#endif
+ return (0);
+ }
+EOF
+
+ ac_save_CPPFLAGS=$CPPFLAGS
+ if test "$ac_ssl_includes" != "/usr/include"; then
+ CPPFLAGS="$CPPFLAGS -I$ac_ssl_includes"
+ fi
+
+ if AC_TRY_EVAL(ac_link); then
+
+ if eval `./conftest 2>&5`; then
+ if test $ssl_version = error; then
+ AC_MSG_ERROR([$ssl_incdir/openssl/opensslv.h doesn't define OPENSSL_VERSION_NUMBER !])
+ else
+ if test $ssl_version = old; then
+ AC_MSG_WARN([OpenSSL version too old. Upgrade to 0.9.6 at least, see http://www.openssl.org. SSL support disabled.])
+ have_ssl=no
+ fi
+ fi
+ ac_cv_ssl_version="ssl_version=$ssl_version"
+ else
+ AC_MSG_ERROR([Your system couldn't run a small SSL test program.
+ Check config.log, and if you can't figure it out, send a mail to
+ David Faure <faure@kde.org>, attaching your config.log])
+ fi
+
+ else
+ AC_MSG_ERROR([Your system couldn't link a small SSL test program.
+ Check config.log, and if you can't figure it out, send a mail to
+ David Faure <faure@kde.org>, attaching your config.log])
+ fi
+ CPPFLAGS=$ac_save_CPPFLAGS
+
+ ])
+
+ eval "$ac_cv_ssl_version"
+ AC_MSG_RESULT($ssl_version)
+fi
+
+if test "$have_ssl" != yes; then
+ LIBSSL="";
+else
+ AC_DEFINE(HAVE_SSL, 1, [If we are going to use OpenSSL])
+ ac_cv_have_ssl="have_ssl=yes \
+ ac_ssl_includes=$ac_ssl_includes ac_ssl_libraries=$ac_ssl_libraries ac_ssl_rsaref=$ac_ssl_rsaref"
+
+
+ ssl_libraries="$ac_ssl_libraries"
+ ssl_includes="$ac_ssl_includes"
+
+ if test "$ac_ssl_rsaref" = yes; then
+ LIBSSL="-lssl -lcrypto -lRSAglue -lrsaref"
+ fi
+
+ if test $ssl_version = "old"; then
+ AC_DEFINE(HAVE_OLD_SSL_API, 1, [Define if you have OpenSSL < 0.9.6])
+ fi
+fi
+
+SSL_INCLUDES=
+
+if test "$ssl_includes" = "/usr/include"; then
+ if test -f /usr/kerberos/include/krb5.h; then
+ SSL_INCLUDES="-I/usr/kerberos/include"
+ fi
+elif test "$ssl_includes" != "/usr/local/include" && test -n "$ssl_includes"; then
+ SSL_INCLUDES="-I$ssl_includes"
+fi
+
+if test "$ssl_libraries" = "/usr/lib" || test "$ssl_libraries" = "/usr/local/lib" || test -z "$ssl_libraries" || test "$ssl_libraries" = "NONE"; then
+ SSL_LDFLAGS=""
+else
+ SSL_LDFLAGS="-L$ssl_libraries -R$ssl_libraries"
+fi
+
+AC_SUBST(SSL_INCLUDES)
+AC_SUBST(SSL_LDFLAGS)
+AC_SUBST(LIBSSL)
+])
+
+AC_DEFUN([KDE_CHECK_STRLCPY],
+[
+ AC_REQUIRE([AC_CHECK_STRLCAT])
+ AC_REQUIRE([AC_CHECK_STRLCPY])
+ AC_CHECK_SIZEOF(size_t)
+ AC_CHECK_SIZEOF(unsigned long)
+
+ AC_MSG_CHECKING([sizeof size_t == sizeof unsigned long])
+ AC_TRY_COMPILE(,[
+ #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_LONG
+ choke me
+ #endif
+ ],AC_MSG_RESULT([yes]),[
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([
+ Apparently on your system our assumption sizeof size_t == sizeof unsigned long
+ does not apply. Please mail kde-devel@kde.org with a description of your system!
+ ])
+ ])
+])
+
+AC_DEFUN([KDE_CHECK_BINUTILS],
+[
+ AC_MSG_CHECKING([if ld supports unversioned version maps])
+
+ kde_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
+ echo "{ local: extern \"C++\" { foo }; };" > conftest.map
+ AC_TRY_LINK([int foo;],
+[
+#ifdef __INTEL_COMPILER
+icc apparently does not support libtools version-info and version-script
+at the same time. Dunno where the bug is, but until somebody figured out,
+better disable the optional version scripts.
+#endif
+
+ foo = 42;
+], kde_supports_versionmaps=yes, kde_supports_versionmaps=no)
+ LDFLAGS="$kde_save_LDFLAGS"
+ rm -f conftest.map
+ AM_CONDITIONAL(include_VERSION_SCRIPT,
+ [test "$kde_supports_versionmaps" = "yes" && test "$kde_use_debug_code" = "no"])
+
+ AC_MSG_RESULT($kde_supports_versionmaps)
+])
+
+AC_DEFUN([AM_PROG_OBJC],[
+AC_CHECK_PROGS(OBJC, gcc, gcc)
+test -z "$OBJC" && AC_MSG_ERROR([no acceptable objective-c gcc found in \$PATH])
+if test "x${OBJCFLAGS-unset}" = xunset; then
+ OBJCFLAGS="-g -O2"
+fi
+AC_SUBST(OBJCFLAGS)
+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES(OBJC)])
+])
+
+AC_DEFUN([KDE_CHECK_PERL],
+[
+ KDE_FIND_PATH(perl, PERL, [$bindir $exec_prefix/bin $prefix/bin], [
+ AC_MSG_ERROR([No Perl found in your $PATH.
+We need perl to generate some code.])
+ ])
+ AC_SUBST(PERL)
+])
+
+AC_DEFUN([KDE_CHECK_LARGEFILE],
+[
+AC_SYS_LARGEFILE
+if test "$ac_cv_sys_file_offset_bits" != no; then
+ CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+fi
+
+if test "x$ac_cv_sys_large_files" != "xno"; then
+ CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=1"
+fi
+
+])
+
+dnl A small extension to PKG_CHECK_MODULES (defined in pkg.m4.in)
+dnl which allows to search for libs that get installed into the KDE prefix.
+dnl
+dnl Syntax: KDE_PKG_CHECK_MODULES(KSTUFF, libkexif >= 0.2 glib = 1.3.4, action-if, action-not)
+dnl defines KSTUFF_LIBS, KSTUFF_CFLAGS, see pkg-config man page
+dnl also defines KSTUFF_PKG_ERRORS on error
+AC_DEFUN([KDE_PKG_CHECK_MODULES], [
+
+ PKG_CONFIG_PATH="$prefix/lib${kdelibsuff}/pkgconfig:$PKG_CONFIG_PATH"
+ if test "$prefix" != "$kde_libs_prefix"; then
+ PKG_CONFIG_PATH="$kde_libs_prefix/lib${kdelibsuff}/pkgconfig:$PKG_CONFIG_PATH"
+ fi
+ export PKG_CONFIG_PATH
+ PKG_CHECK_MODULES([$1],[$2],[$3],[$4])
+])
+
+
+dnl Check for PIE support in the compiler and linker
+AC_DEFUN([KDE_CHECK_PIE_SUPPORT],
+[
+ AC_CACHE_CHECK([for PIE support], kde_cv_val_pie_support,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ safe_CXXFLAGS=$CXXFLAGS
+ safe_LDFLAGS=$LDFLAGS
+ CXXFLAGS="$CXXFLAGS -fPIE"
+ LDFLAGS="$LDFLAGS -pie"
+
+ AC_TRY_LINK([int foo;], [], [kde_cv_val_pie_support=yes], [kde_cv_val_pie_support=no])
+
+ CXXFLAGS=$safe_CXXFLAGS
+ LDFLAGS=$safe_LDFLAGS
+ AC_LANG_RESTORE
+ ])
+
+ AC_MSG_CHECKING(if enabling -pie/fPIE support)
+
+ AC_ARG_ENABLE(pie,
+ AC_HELP_STRING([--enable-pie],[platform supports PIE linking [default=detect]]),
+ [kde_has_pie_support=$enableval],
+ [kde_has_pie_support=detect])
+
+ if test "$kde_has_pie_support" = "detect"; then
+ kde_has_pie_support=$kde_cv_val_pie_support
+ fi
+
+ AC_MSG_RESULT([$kde_has_pie_support])
+
+ KDE_USE_FPIE=""
+ KDE_USE_PIE=""
+
+ AC_SUBST([KDE_USE_FPIE])
+ AC_SUBST([KDE_USE_PIE])
+
+ if test "$kde_has_pie_support" = "yes"; then
+ KDE_USE_FPIE="-fPIE"
+ KDE_USE_PIE="-pie"
+ fi
+])
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 47 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+ [],
+ [m4_define([AC_PROVIDE_IFELSE],
+ [m4_ifdef([AC_PROVIDE_$1],
+ [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+ AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [AC_LIBTOOL_CXX],
+ [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+ ])])
+dnl And a similar setup for Fortran 77 support
+ AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [AC_LIBTOOL_F77],
+ [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [ifdef([AC_PROG_GCJ],
+ [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+ ifdef([A][M_PROG_GCJ],
+ [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+ ifdef([LT_AC_PROG_GCJ],
+ [define([LT_AC_PROG_GCJ],
+ defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool --silent'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ ;;
+ *)
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ AC_PATH_MAGIC
+ fi
+ ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+ [AC_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+ [AC_HELP_STRING([--with-pic],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [pic_mode="$withval"],
+ [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+[$]*
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AC_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LINUX_64_MODE="32"
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ LINUX_64_MODE="64"
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+ ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test ! -s conftest.err; then
+ $2=yes
+ fi
+ fi
+ $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ ifelse([$5], , :, [$5])
+else
+ ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ printf "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ else
+ $2=yes
+ fi
+ fi
+ $rm conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ ifelse([$4], , :, [$4])
+else
+ ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ testring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ *)
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$testring" 2>/dev/null` \
+ = "XX$testring") >/dev/null 2>&1 &&
+ new_result=`expr "X$testring" : ".*" 2>&1` &&
+ lt_cv_sys_max_cmd_len=$new_result &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ testring=$testring$testring
+ done
+ testring=
+ # Add a significant safety factor because C++ compilers can tack on massive
+ # amounts of additional arguments before passing them to the linker.
+ # It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}]
+EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_unknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $rm -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ # According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+ # that will create temporary files in the current directory regardless of
+ # the output directory. Thus, making CWD read-only will cause this test
+ # to fail, enabling locking or at least warning the user not to do parallel
+ # builds.
+ chmod -w .
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test ! -s out/conftest.err; then
+ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w .
+ $rm conftest* out/*
+ rmdir out
+ cd ..
+ rmdir conftest
+ $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+ test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \
+ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then
+
+ # We can hardcode non-existant directories.
+ if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_AC_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ shrext=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext='$(test .$module = .yes && echo .so || echo .dylib)'
+ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+ fi
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+kfreebsd*-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ *) # from 3.2 on
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case "$host_cpu" in
+ ia64*)
+ shrext='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ libsuff=
+ if test "x$LINUX_64_MODE" = x64; then
+ # Some platforms are per default 64-bit, so there's no /lib64
+ if test -d /lib64 -a ! -h /lib64; then
+ libsuff=64
+ fi
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
+ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+nto-qnx*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+ [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+ [include additional configurations @<:@automatic@:>@])],
+ [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+ if test ! -f "${ofile}"; then
+ AC_MSG_WARN([output file `$ofile' does not exist])
+ fi
+
+ if test -z "$LTCC"; then
+ eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+ if test -z "$LTCC"; then
+ AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+ else
+ AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+ fi
+ fi
+
+ # Extract list of available tagged configurations in $ofile.
+ # Note that this assumes the entire list is on one line.
+ available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for tagname in $tagnames; do
+ IFS="$lt_save_ifs"
+ # Check whether tagname contains only valid characters
+ case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+ "") ;;
+ *) AC_MSG_ERROR([invalid tag name: $tagname])
+ ;;
+ esac
+
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+ then
+ AC_MSG_ERROR([tag name \"$tagname\" already exists])
+ fi
+
+ # Update the list of available tags.
+ if test -n "$tagname"; then
+ echo appending configuration tag \"$tagname\" to $ofile
+
+ case $tagname in
+ CXX)
+ if test -n "$CXX" && test "X$CXX" != "Xno"; then
+ AC_LIBTOOL_LANG_CXX_CONFIG
+ else
+ tagname=""
+ fi
+ ;;
+
+ F77)
+ if test -n "$F77" && test "X$F77" != "Xno"; then
+ AC_LIBTOOL_LANG_F77_CONFIG
+ else
+ tagname=""
+ fi
+ ;;
+
+ GCJ)
+ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+ AC_LIBTOOL_LANG_GCJ_CONFIG
+ else
+ tagname=""
+ fi
+ ;;
+
+ RC)
+ AC_LIBTOOL_LANG_RC_CONFIG
+ ;;
+
+ *)
+ AC_MSG_ERROR([Unsupported tag name: $tagname])
+ ;;
+ esac
+
+ # Append the new tag name to the list of available tags.
+ if test -n "$tagname" ; then
+ available_tags="$available_tags $tagname"
+ fi
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ # Now substitute the updated list of available tags.
+ if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+ mv "${ofile}T" "$ofile"
+ chmod +x "$ofile"
+ else
+ rm -f "${ofile}T"
+ AC_MSG_ERROR([unable to update list of available tagged configurations.])
+ fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+ [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+#- set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+ [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+ [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+ [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+ [AC_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+mingw* | pw32*)
+ # win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='win32_libid'
+ ;;
+
+darwin* | rhapsody*)
+ # this will be overwritten by pass_all, but leave it in just in case
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ lt_cv_file_magic_test_file=`/System/Library/Frameworks/System.framework/System`
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | kfreebsd*-gnu)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case "$host_cpu" in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ irix5* | nonstopux*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | ia64* | m68* | mips* | powerpc* | sparc* | s390* | sh* | x86_64* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ # the debian people say, arm and glibc 2.3.1 works for them with pass_all
+ arm* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+nto-qnx*)
+ lt_cv_deplibs_check_method=unknown
+ ;;
+
+openbsd*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+ else
+ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/${ac_tool_prefix}nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If
+# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments. Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If
+# DIRECTORY is not provided and an installed libltdl is not found, it is
+# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/'
+# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
+# quotes!). If your package is not flat and you're not using automake,
+# define top_builddir and top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, lt_dlinit,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ LTDLINCL=
+ fi
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+ [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+ [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+ [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# --------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+#
+# Check for any special shared library compilation flags.
+#
+_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)=
+if test "$GCC" = no; then
+ case $host_os in
+ sco3.2v5*)
+ _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf'
+ ;;
+ esac
+fi
+if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then
+ AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries])
+ if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$]_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[[ ]]" >/dev/null; then :
+ else
+ AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure])
+ _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no
+ fi
+fi
+
+
+#
+# Check to make sure the static flag actually works.
+#
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works],
+ _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+ $_LT_AC_TAGVAR(lt_prog_compiler_static, $1),
+ [],
+ [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+# Report which librarie types wil actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cc
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+ unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+ unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ AC_PROG_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+ grep 'no-whole-archive' > /dev/null; then
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # KDE requires run time linking. Make it the default.
+ aix_use_runtimelinking=yes
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_AC_TAGVAR(archive_cmds, $1)=''
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ else
+ # We have old collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='-qmkshrobj ${wl}-G'
+ else
+ shared_flag='-qmkshrobj'
+ fi
+ fi
+ fi
+
+ # Let the compiler handle the export list.
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_AC_TAGVAR(archive_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '" $shared_flag"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # -bexpall does not export symbols beginning with underscore (_)
+ _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds it's shared libraries.
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=no
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ lt_int_apple_cc_single_mod=no
+ output_verbose_link_cmd='echo'
+ if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+ lt_int_apple_cc_single_mod=yes
+ fi
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring'
+ fi
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs'
+
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ freebsd[12]*)
+ # C++ shared libraries reported to be fairly broken before switch to ELF
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ freebsd-elf*)
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+ freebsd* | kfreebsd*-gnu)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+ gnu*)
+ ;;
+ hpux9*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ case "$host_cpu" in
+ hppa*64*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+ *)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case "$host_cpu" in
+ hppa*64*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ *)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC)
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case "$host_cpu" in
+ ia64*|hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC)
+ # SGI C++
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+ fi
+ fi
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+ linux*)
+ case $cc_basename in
+ KCC)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc)
+ # Intel C++
+ with_gnu_ld=yes
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ cxx)
+ # Compaq C++
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+ osf3*)
+ case $cc_basename in
+ KCC)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+ ;;
+ RCC)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ osf4* | osf5*)
+ case $cc_basename in
+ KCC)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+ ;;
+ RCC)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~
+ $rm $lib.exp'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ sco*)
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ case $cc_basename in
+ CC)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~$rm $lib.exp'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The C++ compiler is used as linker so we must use $wl
+ # flag to pass the commands to the underlying system
+ # linker.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx)
+ # Green Hills C++ Compiler
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | grep -v '^2\.7' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-h $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~$rm $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-h $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~$rm $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+ fi
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ fi
+ ;;
+ esac
+ ;;
+ sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ # The `*' in the case matches for architectures that use `case' in
+ # $output_verbose_cmd can trigger glob expansion during the loop
+ # eval without this substitution.
+ output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+
+ for p in `eval $output_verbose_link_cmd`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" \
+ || test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+ _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext|*.$libext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+ _LT_AC_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+ _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code=" subroutine t\n return\n end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=" program t\n end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+aix4*)
+ test "$enable_shared" = yes && enable_static=no
+ ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars. Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ # See if we are running on zsh, and set the options which allow our commands through
+ # without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+ old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+ deplibs_check_method reload_flag reload_cmds need_locks \
+ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ old_postinstall_cmds old_postuninstall_cmds \
+ _LT_AC_TAGVAR(compiler, $1) \
+ _LT_AC_TAGVAR(CC, $1) \
+ _LT_AC_TAGVAR(LD, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+ _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+ _LT_AC_TAGVAR(old_archive_cmds, $1) \
+ _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+ _LT_AC_TAGVAR(predep_objects, $1) \
+ _LT_AC_TAGVAR(postdep_objects, $1) \
+ _LT_AC_TAGVAR(predeps, $1) \
+ _LT_AC_TAGVAR(postdeps, $1) \
+ _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+ _LT_AC_TAGVAR(archive_cmds, $1) \
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+ _LT_AC_TAGVAR(postinstall_cmds, $1) \
+ _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+ _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+ _LT_AC_TAGVAR(no_undefined_flag, $1) \
+ _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+ _LT_AC_TAGVAR(hardcode_automatic, $1) \
+ _LT_AC_TAGVAR(module_cmds, $1) \
+ _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+ _LT_AC_TAGVAR(exclude_expsyms, $1) \
+ _LT_AC_TAGVAR(include_expsyms, $1); do
+
+ case $var in
+ _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+ _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+ _LT_AC_TAGVAR(archive_cmds, $1) | \
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+ _LT_AC_TAGVAR(module_cmds, $1) | \
+ _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+ _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+ extract_expsyms_cmds | reload_cmds | finish_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case $lt_echo in
+ *'\[$]0 --fallback-echo"')
+ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+ ;;
+ esac
+
+ifelse([$1], [],
+ [cfgfile="${ofile}T"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ $rm -f "$cfgfile"
+ AC_MSG_NOTICE([creating $ofile])],
+ [cfgfile="$ofile"])
+
+ cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext='$shrext'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" || \
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+])
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ test -f Makefile && make "$ltmain"
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+ AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris* | sysv5*)
+ symcode='[[BDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGISTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if grep ' nm_test_var$' "$nlist" >/dev/null; then
+ if grep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | os2* | pw32*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix4* | aix5*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68)
+ # Green Hills C++ Compiler
+ # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx)
+ # Green Hills C++ Compiler
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | kfreebsd*-gnu)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+ if test "$host_cpu" != ia64; then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux*)
+ case $cc_basename in
+ KCC)
+ # KAI C++ Compiler
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ icpc)
+ # Intel C++
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ cxx)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC)
+ # Rational C++ 2.4.1
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx)
+ # Digital/Compaq C++
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ sco*)
+ case $cc_basename in
+ CC)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx)
+ # Green Hills C++ Compiler
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC)
+ # Sun C++ 4.x
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc)
+ # Lucid
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC)
+ # NonStop-UX NCC 3.20
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ unixware*)
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+
+ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ hpux*)
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ newsos6)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ linux*)
+ case $CC in
+ icc* | ecc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ ccc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ esac
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn'
+ ;;
+
+ solaris*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sunos4*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ uts4*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+ _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+ [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case "$host_os" in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix4* | aix5*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw*)
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ *)
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+],[
+ runpath_var=
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_AC_TAGVAR(archive_cmds, $1)=
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+ _LT_AC_TAGVAR(module_cmds, $1)=
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_AC_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ fi
+ ;;
+
+ amigaos*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can't use
+ # them.
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=no
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $compiler_flags $libobjs $deplibs -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sunos4*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then
+ runpath_var=LD_RUN_PATH
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ fi
+
+ # KDE requires run time linking. Make it the default.
+ aix_use_runtimelinking=yes
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_AC_TAGVAR(archive_cmds, $1)=''
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ else
+ # We have old collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='-qmkshrobj ${wl}-G'
+ else
+ shared_flag='-qmkshrobj'
+ fi
+ fi
+ fi
+
+ # Let the compiler handle the export list.
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_AC_TAGVAR(archive_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '" $shared_flag"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # -bexpall does not export symbols beginning with underscore (_)
+ _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds it's shared libraries.
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ # see comment about different semantics on the GNU ld section
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ bsdi4*)
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=no
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $compiler_flags $libobjs `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ darwin* | rhapsody*)
+ if test "$GXX" = yes ; then
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ lt_int_apple_cc_single_mod=no
+ output_verbose_link_cmd='echo'
+ if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+ lt_int_apple_cc_single_mod=yes
+ fi
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring'
+ fi
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ dgux*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ freebsd1*)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | kfreebsd*-gnu)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $compiler_flags $libobjs $deplibs'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $compiler_flags $libobjs $deplibs~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10* | hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $compiler_flags $libobjs $deplibs'
+ ;;
+ esac
+ else
+ case "$host_cpu" in
+ hppa*64*|ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ case "$host_cpu" in
+ hppa*64*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ *)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ openbsd*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $compiler_flags $libobjs $deplibs'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $compiler_flags $libobjs $deplibs'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $compiler_flags $libobjs $deplibs$output_objdir/$libname.def'
+ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $libobjs $deplibs ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $libobjs $deplibs ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ sco3.2v5*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ;;
+
+ solaris*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs~$rm $lib.exp'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+ esac
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $compiler_flags $libobjs $deplibs'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text'
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs'
+ fi
+ runpath_var='LD_RUN_PATH'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv5*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_AC_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ $rm conftest*
+ printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+ then
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $rm conftest*
+ AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+ ;;
+ esac
+ fi
+ ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && break
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_MSG_RESULT([$SED])
+])
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..e122e76
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,3073 @@
+# generated automatically by aclocal 1.10 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_if(m4_PACKAGE_VERSION, [2.61],,
+[m4_fatal([this file was generated for autoconf 2.61.
+You have another version of autoconf. If you want to use that,
+you should regenerate the build system entirely.], [63])])
+
+# gettext.m4 serial 59 (gettext-0.16.1)
+dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006.
+
+dnl Macro to add for using GNU gettext.
+
+dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
+dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
+dnl default (if it is not specified or empty) is 'no-libtool'.
+dnl INTLSYMBOL should be 'external' for packages with no intl directory,
+dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory.
+dnl If INTLSYMBOL is 'use-libtool', then a libtool library
+dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
+dnl depending on --{enable,disable}-{shared,static} and on the presence of
+dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
+dnl $(top_builddir)/intl/libintl.a will be created.
+dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
+dnl implementations (in libc or libintl) without the ngettext() function
+dnl will be ignored. If NEEDSYMBOL is specified and is
+dnl 'need-formatstring-macros', then GNU gettext implementations that don't
+dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
+dnl INTLDIR is used to find the intl libraries. If empty,
+dnl the value `$(top_builddir)/intl/' is used.
+dnl
+dnl The result of the configuration is one of three cases:
+dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
+dnl and used.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 2) GNU gettext has been found in the system's C library.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 3) No internationalization, always use English msgid.
+dnl Catalog format: none
+dnl Catalog extension: none
+dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
+dnl The use of .gmo is historical (it was needed to avoid overwriting the
+dnl GNU format catalogs when building on a platform with an X/Open gettext),
+dnl but we keep it in order not to force irrelevant filename changes on the
+dnl maintainers.
+dnl
+AC_DEFUN([AM_GNU_GETTEXT],
+[
+ dnl Argument checking.
+ ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
+ [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
+])])])])])
+ ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
+ [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
+])])])])
+ define([gt_included_intl],
+ ifelse([$1], [external],
+ ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
+ [yes]))
+ define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+ gt_NEEDS_INIT
+ AM_GNU_GETTEXT_NEED([$2])
+
+ AC_REQUIRE([AM_PO_SUBDIRS])dnl
+ ifelse(gt_included_intl, yes, [
+ AC_REQUIRE([AM_INTL_SUBDIR])dnl
+ ])
+
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ dnl Ideally we would do this search only after the
+ dnl if test "$USE_NLS" = "yes"; then
+ dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+ dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
+ dnl the configure script would need to contain the same shell code
+ dnl again, outside any 'if'. There are two solutions:
+ dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
+ dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
+ dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
+ dnl documented, we avoid it.
+ ifelse(gt_included_intl, yes, , [
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+ ])
+
+ dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
+ gt_INTL_MACOSX
+
+ dnl Set USE_NLS.
+ AC_REQUIRE([AM_NLS])
+
+ ifelse(gt_included_intl, yes, [
+ BUILD_INCLUDED_LIBINTL=no
+ USE_INCLUDED_LIBINTL=no
+ ])
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ dnl Add a version number to the cache macros.
+ case " $gt_needs " in
+ *" need-formatstring-macros "*) gt_api_version=3 ;;
+ *" need-ngettext "*) gt_api_version=2 ;;
+ *) gt_api_version=1 ;;
+ esac
+ gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+ gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ gt_use_preinstalled_gnugettext=no
+ ifelse(gt_included_intl, yes, [
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ ])
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If GNU gettext is available we use this. Else we have
+ dnl to fall back to GNU NLS library.
+
+ if test $gt_api_version -ge 3; then
+ gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+'
+ else
+ gt_revision_test_code=
+ fi
+ if test $gt_api_version -ge 2; then
+ gt_expression_test_code=' + * ngettext ("", "", 0)'
+ else
+ gt_expression_test_code=
+ fi
+
+ AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
+ [AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
+ [eval "$gt_func_gnugettext_libc=yes"],
+ [eval "$gt_func_gnugettext_libc=no"])])
+
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ ifelse(gt_included_intl, yes, , [
+ AM_ICONV_LINK
+ ])
+ dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
+ dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
+ dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
+ dnl even if libiconv doesn't exist.
+ AC_LIB_LINKFLAGS_BODY([intl])
+ AC_CACHE_CHECK([for GNU gettext in libintl],
+ [$gt_func_gnugettext_libintl],
+ [gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $INCINTL"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBINTL"
+ dnl Now see whether libintl exists and does not depend on libiconv.
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [eval "$gt_func_gnugettext_libintl=yes"],
+ [eval "$gt_func_gnugettext_libintl=no"])
+ dnl Now see whether libintl exists and depends on libiconv.
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_func_gnugettext_libintl=yes"
+ ])
+ fi
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"])
+ fi
+
+ dnl If an already present or preinstalled GNU gettext() is found,
+ dnl use it. But if this macro is used in GNU gettext, and GNU
+ dnl gettext is already preinstalled in libintl, we update this
+ dnl libintl. (Cf. the install rule in intl/Makefile.in.)
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
+ && test "$PACKAGE" != gettext-runtime \
+ && test "$PACKAGE" != gettext-tools; }; then
+ gt_use_preinstalled_gnugettext=yes
+ else
+ dnl Reset the values set by searching for libintl.
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ if test "$gt_use_preinstalled_gnugettext" != "yes"; then
+ dnl GNU gettext is not found in the C library.
+ dnl Fall back on included GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ BUILD_INCLUDED_LIBINTL=yes
+ USE_INCLUDED_LIBINTL=yes
+ LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
+ LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
+ LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
+ fi
+
+ CATOBJEXT=
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions to use GNU gettext tools.
+ CATOBJEXT=.gmo
+ fi
+ ])
+
+ if test -n "$INTL_MACOSX_LIBS"; then
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Some extra flags are needed during linking.
+ LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+ LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+ fi
+ fi
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1,
+ [Define to 1 if translation of program messages to the user's native language
+ is requested.])
+ else
+ USE_NLS=no
+ fi
+ fi
+
+ AC_MSG_CHECKING([whether to use NLS])
+ AC_MSG_RESULT([$USE_NLS])
+ if test "$USE_NLS" = "yes"; then
+ AC_MSG_CHECKING([where the gettext function comes from])
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+ gt_source="external libintl"
+ else
+ gt_source="libc"
+ fi
+ else
+ gt_source="included intl directory"
+ fi
+ AC_MSG_RESULT([$gt_source])
+ fi
+
+ if test "$USE_NLS" = "yes"; then
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+ AC_MSG_CHECKING([how to link with libintl])
+ AC_MSG_RESULT([$LIBINTL])
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
+ fi
+
+ dnl For backward compatibility. Some packages may be using this.
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define if the GNU gettext() function is already present or preinstalled.])
+ AC_DEFINE(HAVE_DCGETTEXT, 1,
+ [Define if the GNU dcgettext() function is already present or preinstalled.])
+ fi
+
+ dnl We need to process the po/ directory.
+ POSUB=po
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
+ dnl to 'yes' because some of the testsuite requires it.
+ if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
+ BUILD_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(BUILD_INCLUDED_LIBINTL)
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATOBJEXT)
+
+ dnl For backward compatibility. Some configure.ins may be using this.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ DATADIRNAME=share
+ AC_SUBST(DATADIRNAME)
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INSTOBJEXT=.mo
+ AC_SUBST(INSTOBJEXT)
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ GENCAT=gencat
+ AC_SUBST(GENCAT)
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLOBJS=
+ if test "$USE_INCLUDED_LIBINTL" = yes; then
+ INTLOBJS="\$(GETTOBJS)"
+ fi
+ AC_SUBST(INTLOBJS)
+
+ dnl Enable libtool support if the surrounding package wishes it.
+ INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
+ AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
+ ])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLLIBS="$LIBINTL"
+ AC_SUBST(INTLLIBS)
+
+ dnl Make all documented variables known to autoconf.
+ AC_SUBST(LIBINTL)
+ AC_SUBST(LTLIBINTL)
+ AC_SUBST(POSUB)
+])
+
+
+dnl Checks for special options needed on MacOS X.
+dnl Defines INTL_MACOSX_LIBS.
+AC_DEFUN([gt_INTL_MACOSX],
+[
+ dnl Check for API introduced in MacOS X 10.2.
+ AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
+ gt_cv_func_CFPreferencesCopyAppValue,
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
+ [CFPreferencesCopyAppValue(NULL, NULL)],
+ [gt_cv_func_CFPreferencesCopyAppValue=yes],
+ [gt_cv_func_CFPreferencesCopyAppValue=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+ AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1,
+ [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
+ fi
+ dnl Check for API introduced in MacOS X 10.3.
+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], gt_cv_func_CFLocaleCopyCurrent,
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
+ [gt_cv_func_CFLocaleCopyCurrent=yes],
+ [gt_cv_func_CFLocaleCopyCurrent=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1,
+ [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+ AC_SUBST([INTL_MACOSX_LIBS])
+])
+
+
+dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
+m4_define([gt_NEEDS_INIT],
+[
+ m4_divert_text([DEFAULTS], [gt_needs=])
+ m4_define([gt_NEEDS_INIT], [])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
+AC_DEFUN([AM_GNU_GETTEXT_NEED],
+[
+ m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
+
+# iconv.m4 serial AM4 (gettext-0.11.3)
+dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+ dnl those with the standalone portable GNU libiconv installed).
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+ dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed libiconv and not disabled its use
+ dnl via --without-libiconv-prefix, he wants to use it. The first
+ dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
+ am_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+ AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ am_cv_func_iconv=yes)
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ am_cv_lib_iconv=yes
+ am_cv_func_iconv=yes)
+ LIBS="$am_save_LIBS"
+ fi
+ ])
+ if test "$am_cv_func_iconv" = yes; then
+ AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ AC_MSG_CHECKING([how to link with libiconv])
+ AC_MSG_RESULT([$LIBICONV])
+ else
+ dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+ dnl either.
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+ AC_SUBST(LIBICONV)
+ AC_SUBST(LTLIBICONV)
+])
+
+AC_DEFUN([AM_ICONV],
+[
+ AM_ICONV_LINK
+ if test "$am_cv_func_iconv" = yes; then
+ AC_MSG_CHECKING([for iconv declaration])
+ AC_CACHE_VAL(am_cv_proto_iconv, [
+ AC_TRY_COMPILE([
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+ AC_MSG_RESULT([$]{ac_t:-
+ }[$]am_cv_proto_iconv)
+ AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
+ [Define as const if the declaration of iconv() needs const.])
+ fi
+])
+
+# lib-ld.m4 serial 3 (gettext-0.13)
+dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Subroutines of libtool.m4,
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
+
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ acl_cv_prog_gnu_ld=yes ;;
+*)
+ acl_cv_prog_gnu_ld=no ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-1.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ [re_direlt='/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(acl_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ acl_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break ;;
+ *)
+ test "$with_gnu_ld" != yes && break ;;
+ esac
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_LIB_PROG_LD_GNU
+])
+
+# lib-link.m4 serial 9 (gettext-0.16)
+dnl Copyright (C) 2001-2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ(2.50)
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ define([Name],[translit([$1],[./-], [___])])
+ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+ ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+ ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+ ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+ ])
+ LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+ INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+ dnl results of this search when this library appears as a dependency.
+ HAVE_LIB[]NAME=yes
+ undefine([Name])
+ undefine([NAME])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. If found, it
+dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
+dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ define([Name],[translit([$1],[./-], [___])])
+ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+
+ dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+ dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed lib[]Name and not disabled its use
+ dnl via --without-lib[]Name-prefix, he wants to use it.
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+ AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIB[]NAME"
+ AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
+ LIBS="$ac_save_LIBS"
+ ])
+ if test "$ac_cv_lib[]Name" = yes; then
+ HAVE_LIB[]NAME=yes
+ AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
+ AC_MSG_CHECKING([how to link with lib[]$1])
+ AC_MSG_RESULT([$LIB[]NAME])
+ else
+ HAVE_LIB[]NAME=no
+ dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+ dnl $INC[]NAME either.
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIB[]NAME=
+ LTLIB[]NAME=
+ fi
+ AC_SUBST([HAVE_LIB]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ undefine([Name])
+ undefine([NAME])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator,
+dnl hardcode_direct, hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+ dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+ m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
+ AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
+ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+ AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
+ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+ . ./conftest.sh
+ rm -f ./conftest.sh
+ acl_cv_rpath=done
+ ])
+ wl="$acl_cv_wl"
+ libext="$acl_cv_libext"
+ shlibext="$acl_cv_shlibext"
+ hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ hardcode_direct="$acl_cv_hardcode_direct"
+ hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ dnl Determine whether the user wants rpath handling at all.
+ AC_ARG_ENABLE(rpath,
+ [ --disable-rpath do not hardcode runtime library paths],
+ :, enable_rpath=yes)
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib$1-prefix],
+[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib
+ --without-lib$1-prefix don't search for lib$1 in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ fi
+ fi
+])
+ dnl Search the library and its dependencies in $additional_libdir and
+ dnl $LDFLAGS. Using breadth-first-seach.
+ LIB[]NAME=
+ LTLIB[]NAME=
+ INC[]NAME=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='$1 $2'
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+ dnl or AC_LIB_HAVE_LINKFLAGS call.
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
+ else
+ dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+ dnl that this library doesn't exist. So just drop it.
+ :
+ fi
+ else
+ dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+ dnl and the already constructed $LIBNAME/$LTLIBNAME.
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ if test $use_additional = yes; then
+ if test -n "$shlibext" \
+ && { test -f "$additional_libdir/lib$name.$shlibext" \
+ || { test "$shlibext" = dll \
+ && test -f "$additional_libdir/lib$name.dll.a"; }; }; then
+ found_dir="$additional_libdir"
+ if test -f "$additional_libdir/lib$name.$shlibext"; then
+ found_so="$additional_libdir/lib$name.$shlibext"
+ else
+ found_so="$additional_libdir/lib$name.dll.a"
+ fi
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ else
+ if test -f "$additional_libdir/lib$name.$libext"; then
+ found_dir="$additional_libdir"
+ found_a="$additional_libdir/lib$name.$libext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ if test -n "$shlibext" \
+ && { test -f "$dir/lib$name.$shlibext" \
+ || { test "$shlibext" = dll \
+ && test -f "$dir/lib$name.dll.a"; }; }; then
+ found_dir="$dir"
+ if test -f "$dir/lib$name.$shlibext"; then
+ found_so="$dir/lib$name.$shlibext"
+ else
+ found_so="$dir/lib$name.dll.a"
+ fi
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ else
+ if test -f "$dir/lib$name.$libext"; then
+ found_dir="$dir"
+ found_a="$dir/lib$name.$libext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ dnl Found the library.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ dnl Linking with a shared library. We attempt to hardcode its
+ dnl directory into the executable's runpath, unless it's the
+ dnl standard /usr/lib.
+ if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then
+ dnl No hardcoding is needed.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ dnl The hardcoding into $LIBNAME is system dependent.
+ if test "$hardcode_direct" = yes; then
+ dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+ dnl resulting binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ dnl Rely on "-L$found_dir".
+ dnl But don't add it if it's already contained in the LDFLAGS
+ dnl or the already constructed $LIBNAME
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+ fi
+ if test "$hardcode_minus_L" != no; then
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH
+ dnl here, because this doesn't fit in flags passed to the
+ dnl compiler. So give up. No hardcoding. This affects only
+ dnl very old systems.
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ dnl Linking with a static library.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+ else
+ dnl We shouldn't come here, but anyway it's good to have a
+ dnl fallback.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+ fi
+ fi
+ dnl Assume the include files are nearby.
+ additional_includedir=
+ case "$found_dir" in
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ dnl Potentially add $additional_includedir to $INCNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 3. if it's already present in $CPPFLAGS or the already
+ dnl constructed $INCNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INC[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $INCNAME.
+ INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ dnl Look for dependencies.
+ if test -n "$found_la"; then
+ dnl Read the .la file. It defines the variables
+ dnl dlname, library_names, old_library, dependency_libs, current,
+ dnl age, revision, installed, dlopen, dlpreopen, libdir.
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ dnl We use only dependency_libs.
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 3. if it's already present in $LDFLAGS or the already
+ dnl constructed $LIBNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LIBNAME.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LTLIBNAME.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ dnl Handle this in the next round.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ dnl Handle this in the next round. Throw away the .la's
+ dnl directory; it is already contained in a preceding -L
+ dnl option.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+ ;;
+ *)
+ dnl Most likely an immediate library name.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ dnl Didn't find the library; assume it is in the system directories
+ dnl known to the linker and runtime loader. (All the system
+ dnl directories known to the linker should also be known to the
+ dnl runtime loader, otherwise the system is severely misconfigured.)
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user must
+ dnl pass all path elements in one option. We can arrange that for a
+ dnl single library, but not when more than one $LIBNAMEs are used.
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
+ done
+ dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl.
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ dnl When using libtool, the option that works for both libraries and
+ dnl executables is -R. The -R options are cumulative.
+ for found_dir in $ltrpathdirs; do
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+ done
+ fi
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+ for element in [$2]; do
+ haveit=
+ for x in $[$1]; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ [$1]="${[$1]}${[$1]:+ }$element"
+ fi
+ done
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+ AC_REQUIRE([AC_LIB_RPATH])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ $1=
+ if test "$enable_rpath" != no; then
+ if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode directories into the resulting
+ dnl binary.
+ rpathdirs=
+ next=
+ for opt in $2; do
+ if test -n "$next"; then
+ dir="$next"
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next=
+ else
+ case $opt in
+ -L) next=yes ;;
+ -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next= ;;
+ *) next= ;;
+ esac
+ fi
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n ""$3""; then
+ dnl libtool is used for linking. Use -R options.
+ for dir in $rpathdirs; do
+ $1="${$1}${$1:+ }-R$dir"
+ done
+ else
+ dnl The linker is used for linking directly.
+ if test -n "$hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user
+ dnl must pass all path elements in one option.
+ alldirs=
+ for dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$dir"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="${$1}${$1:+ }$flag"
+ done
+ fi
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST([$1])
+])
+
+# lib-prefix.m4 serial 5 (gettext-0.15)
+dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+ AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib-prefix],
+[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+ --without-lib-prefix don't search for libraries in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ fi
+ fi
+])
+ if test $use_additional = yes; then
+ dnl Potentially add $additional_includedir to $CPPFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's already present in $CPPFLAGS,
+ dnl 3. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ for x in $CPPFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $CPPFLAGS.
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ dnl Potentially add $additional_libdir to $LDFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's already present in $LDFLAGS,
+ dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+ haveit=
+ for x in $LDFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux*) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LDFLAGS.
+ LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+ dnl Unfortunately, prefix and exec_prefix get only finally determined
+ dnl at the end of configure.
+ if test "X$prefix" = "XNONE"; then
+ acl_final_prefix="$ac_default_prefix"
+ else
+ acl_final_prefix="$prefix"
+ fi
+ if test "X$exec_prefix" = "XNONE"; then
+ acl_final_exec_prefix='${prefix}'
+ else
+ acl_final_exec_prefix="$exec_prefix"
+ fi
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ $1
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing
+dnl the basename of the libdir, either "lib" or "lib64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+ dnl There is no formal standard regarding lib and lib64. The current
+ dnl practice is that on a system supporting 32-bit and 64-bit instruction
+ dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit
+ dnl libraries go under $prefix/lib. We determine the compiler's default
+ dnl mode by looking at the compiler's library search path. If at least
+ dnl of its elements ends in /lib64 or points to a directory whose absolute
+ dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the
+ dnl default, namely "lib".
+ acl_libdirstem=lib
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test -n "$searchpath"; then
+ acl_save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) acl_libdirstem=lib64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$acl_save_IFS"
+ fi
+])
+
+# nls.m4 serial 3 (gettext-0.15)
+dnl Copyright (C) 1995-2003, 2005-2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ(2.50)
+
+AC_DEFUN([AM_NLS],
+[
+ AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+])
+
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists. Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+ if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ else
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+ [pkg_failed=yes])
+ fi
+else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+ [AC_MSG_RESULT([no])
+ $4])
+elif test $pkg_failed = untried; then
+ ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+ [$4])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
+
+# po.m4 serial 13 (gettext-0.15)
+dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ(2.50)
+
+dnl Checks for all prerequisites of the po subdirectory.
+AC_DEFUN([AM_PO_SUBDIRS],
+[
+ AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+ AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
+ AC_REQUIRE([AM_NLS])dnl
+
+ dnl Perform the following tests also if --disable-nls has been given,
+ dnl because they are needed for "make dist" to work.
+
+ dnl Search for GNU msgfmt in the PATH.
+ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
+ dnl The second test excludes FreeBSD msgfmt.
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+
+ dnl Test whether it is GNU msgfmt >= 0.15.
+changequote(,)dnl
+ case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+ *) MSGFMT_015=$MSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([MSGFMT_015])
+changequote(,)dnl
+ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+ *) GMSGFMT_015=$GMSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([GMSGFMT_015])
+
+ dnl Search for GNU xgettext 0.12 or newer in the PATH.
+ dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
+ dnl The second test excludes FreeBSD xgettext.
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ dnl Remove leftover from FreeBSD xgettext call.
+ rm -f messages.po
+
+ dnl Test whether it is GNU xgettext >= 0.15.
+changequote(,)dnl
+ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+ *) XGETTEXT_015=$XGETTEXT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([XGETTEXT_015])
+
+ dnl Search for GNU msgmerge 0.11 or newer in the PATH.
+ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
+ [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
+
+ dnl Installation directories.
+ dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
+ dnl have to define it here, so that it can be used in po/Makefile.
+ test -n "$localedir" || localedir='${datadir}/locale'
+ AC_SUBST([localedir])
+
+ AC_CONFIG_COMMANDS([po-directories], [[
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ # Treat a directory as a PO directory if and only if it has a
+ # POTFILES.in file. This allows packages to have multiple PO
+ # directories under different names or in different locations.
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done]],
+ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+ # from automake < 1.5.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+ ])
+])
+
+dnl Postprocesses a Makefile in a directory containing PO files.
+AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
+[
+ # When this code is run, in config.status, two variables have already been
+ # set:
+ # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
+ # - LINGUAS is the value of the environment variable LINGUAS at configure
+ # time.
+
+changequote(,)dnl
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ # Find a way to echo strings without interpreting backslash.
+ if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='echo'
+ else
+ if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='printf %s\n'
+ else
+ echo_func () {
+ cat <<EOT
+$*
+EOT
+ }
+ gt_echo='echo_func'
+ fi
+ fi
+
+ # A sed script that extracts the value of VARIABLE from a Makefile.
+ sed_x_variable='
+# Test if the hold space is empty.
+x
+s/P/P/
+x
+ta
+# Yes it was empty. Look if we have the expected variable definition.
+/^[ ]*VARIABLE[ ]*=/{
+ # Seen the first line of the variable definition.
+ s/^[ ]*VARIABLE[ ]*=//
+ ba
+}
+bd
+:a
+# Here we are processing a line from the variable definition.
+# Remove comment, more precisely replace it with a space.
+s/#.*$/ /
+# See if the line ends in a backslash.
+tb
+:b
+s/\\$//
+# Print the line, without the trailing backslash.
+p
+tc
+# There was no trailing backslash. The end of the variable definition is
+# reached. Clear the hold space.
+s/^.*$//
+x
+bd
+:c
+# A trailing backslash means that the variable definition continues in the
+# next line. Put a nonempty string into the hold space to indicate this.
+s/^.*$/P/
+x
+:d
+'
+changequote([,])dnl
+
+ # Set POTFILES to the value of the Makefile variable POTFILES.
+ sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
+ POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
+ # Compute POTFILES_DEPS as
+ # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
+ POTFILES_DEPS=
+ for file in $POTFILES; do
+ POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
+ done
+ POMAKEFILEDEPS=""
+
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
+ sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
+ ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+ fi
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ # Compute PROPERTIESFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+ # Compute CLASSFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+ # Compute QMFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
+ # Compute MSGFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
+ # Compute RESOURCESDLLFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ PROPERTIESFILES=
+ CLASSFILES=
+ QMFILES=
+ MSGFILES=
+ RESOURCESDLLFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
+ CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+ QMFILES="$QMFILES $srcdirpre$lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ JAVACATALOGS=
+ QTCATALOGS=
+ TCLCATALOGS=
+ CSHARPCATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
+ QTCATALOGS="$QTCATALOGS $lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ fi
+
+ sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
+ if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang.msg: $lang.po
+ @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+ \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
+ @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+ \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if test -n "$POMAKEFILEDEPS"; then
+ cat >> "$ac_file.tmp" <<EOF
+Makefile: $POMAKEFILEDEPS
+EOF
+ fi
+ mv "$ac_file.tmp" "$ac_file"
+])
+
+# progtest.m4 serial 4 (gettext-0.14.2)
+dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+AC_PREREQ(2.50)
+
+# Search path for a program which passes the given test.
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST],
+[
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ [[\\/]]* | ?:[[\\/]]*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.10'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.10], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.10])dnl
+_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.60])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/builddeb b/builddeb
new file mode 100755
index 0000000..1c56e6c
--- /dev/null
+++ b/builddeb
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+vers=`cat B/DEBIAN/control | grep Version | sed s/'Version: '//`
+
+make install DESTDIR=`pwd`/B &&
+rm -f B/usr/lib/ksquirrel-libs/*.la &&
+rm -f B/usr/lib/*.la &&
+rm -f B/usr/lib/ksquirrel-libs/*.so &&
+rm -f B/usr/lib/ksquirrel-libs/*.so.0 &&
+strip B/usr/lib/ksquirrel-libs/* &&
+strip B/usr/lib/*
+strip B/usr/bin/*
+dpkg-deb -b B ksquirrel-libs_${vers}_i386.deb &&
+rm -rf B/usr \ No newline at end of file
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..da83314
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1561 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
+
+timestamp='2009-04-27'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[456])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:[3456]*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T | authenticamd | genuineintel)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
+ test x"${LIBC}" != x && {
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit
+ }
+ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.log b/config.log
new file mode 100644
index 0000000..8362775
--- /dev/null
+++ b/config.log
@@ -0,0 +1,355 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by ksquirrel-libs configure 0.8.0, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ $ ./configure --host=x86_64-linux-gnu --build=x86_64-linux-gnu --prefix=/opt/kde3 --mandir=${prefix}/share/man --infodir=${prefix}/share/info CFLAGS=-g -O2 LDFLAGS=-Wl,-z,defs --disable-rpath
+
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = argus4
+uname -m = x86_64
+uname -r = 2.6.31-16-generic
+uname -s = Linux
+uname -v = #53-Ubuntu SMP Tue Dec 8 04:02:15 UTC 2009
+
+/usr/bin/uname -p = unknown
+/bin/uname -X = unknown
+
+/bin/arch = unknown
+/usr/bin/arch -k = unknown
+/usr/convex/getsysinfo = unknown
+/usr/bin/hostinfo = unknown
+/bin/machine = unknown
+/usr/bin/oslevel = unknown
+/bin/universe = unknown
+
+PATH: /opt/kde3/bin
+PATH: /opt/kde3/games
+PATH: /opt/kde3/bin
+PATH: /home/eldarion/bin
+PATH: /usr/local/sbin
+PATH: /usr/local/bin
+PATH: /usr/sbin
+PATH: /usr/bin
+PATH: /sbin
+PATH: /bin
+PATH: /usr/games
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+configure:2155: checking build system type
+configure:2173: result: x86_64-pc-linux-gnu
+configure:2195: checking host system type
+configure:2210: result: x86_64-pc-linux-gnu
+configure:2232: checking target system type
+configure:2247: result: x86_64-pc-linux-gnu
+configure:2309: checking for a BSD-compatible install
+configure:2365: result: /usr/bin/install -c
+configure:2380: checking for -p flag to install
+configure:2393: result: yes
+configure:2404: checking whether build environment is sane
+
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+
+ac_cv_build=x86_64-pc-linux-gnu
+ac_cv_env_CCC_set=
+ac_cv_env_CCC_value=
+ac_cv_env_CC_set=
+ac_cv_env_CC_value=
+ac_cv_env_CFLAGS_set=set
+ac_cv_env_CFLAGS_value='-g -O2'
+ac_cv_env_CPPFLAGS_set=set
+ac_cv_env_CPPFLAGS_value=
+ac_cv_env_CPP_set=
+ac_cv_env_CPP_value=
+ac_cv_env_CXXCPP_set=
+ac_cv_env_CXXCPP_value=
+ac_cv_env_CXXFLAGS_set=set
+ac_cv_env_CXXFLAGS_value='-g -O2'
+ac_cv_env_CXX_set=
+ac_cv_env_CXX_value=
+ac_cv_env_F77_set=
+ac_cv_env_F77_value=
+ac_cv_env_FFLAGS_set=set
+ac_cv_env_FFLAGS_value='-g -O2'
+ac_cv_env_LDFLAGS_set=set
+ac_cv_env_LDFLAGS_value=-Wl,-z,defs
+ac_cv_env_LIBS_set=
+ac_cv_env_LIBS_value=
+ac_cv_env_OpenEXR_CFLAGS_set=
+ac_cv_env_OpenEXR_CFLAGS_value=
+ac_cv_env_OpenEXR_LIBS_set=
+ac_cv_env_OpenEXR_LIBS_value=
+ac_cv_env_PKG_CONFIG_set=
+ac_cv_env_PKG_CONFIG_value=
+ac_cv_env_build_alias_set=set
+ac_cv_env_build_alias_value=x86_64-linux-gnu
+ac_cv_env_host_alias_set=set
+ac_cv_env_host_alias_value=x86_64-linux-gnu
+ac_cv_env_lcms_CFLAGS_set=
+ac_cv_env_lcms_CFLAGS_value=
+ac_cv_env_lcms_LIBS_set=
+ac_cv_env_lcms_LIBS_value=
+ac_cv_env_target_alias_set=
+ac_cv_env_target_alias_value=
+ac_cv_host=x86_64-pc-linux-gnu
+ac_cv_path_install='/usr/bin/install -c'
+ac_cv_target=x86_64-pc-linux-gnu
+
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+
+ACLOCAL=''
+AMDEPBACKSLASH=''
+AMDEP_FALSE=''
+AMDEP_TRUE=''
+AMTAR=''
+AR=''
+AUTOCONF=''
+AUTOHEADER=''
+AUTOMAKE=''
+AWK=''
+CAMERA_NO_CMS_FALSE=''
+CAMERA_NO_CMS_TRUE=''
+CAMERA_NO_JPEG_FALSE=''
+CAMERA_NO_JPEG_TRUE=''
+CC=''
+CCDEPMODE=''
+CFLAGS='-g -O2'
+CPP=''
+CPPFLAGS=''
+CXX=''
+CXXCPP=''
+CXXDEPMODE=''
+CXXFLAGS='-g -O2'
+CYGPATH_W=''
+DEFS=''
+DEPDIR=''
+DJVU=''
+ECHO='echo'
+ECHO_C=''
+ECHO_N='-n'
+ECHO_T=''
+EGREP=''
+ENABLE_PERMISSIVE_FLAG=''
+EPS2PPM=''
+EXEEXT=''
+F77=''
+FFLAGS='-g -O2'
+FREETYPE_CONFIG=''
+GMSGFMT=''
+GMSGFMT_015=''
+GREP=''
+HAVE_GCC_VISIBILITY=''
+ILBMTOPPM=''
+INSTALL_DATA='${INSTALL} -m 644'
+INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
+INSTALL_SCRIPT='${INSTALL}'
+INSTALL_STRIP_PROGRAM=''
+INTLLIBS=''
+INTL_MACOSX_LIBS=''
+KDE_NO_UNDEFINED=''
+KDE_USE_CLOSURE_FALSE=''
+KDE_USE_CLOSURE_TRUE=''
+KDE_USE_FINAL_FALSE=''
+KDE_USE_FINAL_TRUE=''
+KDE_USE_NMCHECK_FALSE=''
+KDE_USE_NMCHECK_TRUE=''
+LDFLAGS='-Wl,-z,defs'
+LDFLAGS_AS_NEEDED=''
+LDFLAGS_NEW_DTAGS=''
+LEAFTOPPM=''
+LIBICONV=''
+LIBINTL=''
+LIBOBJS=''
+LIBS=''
+LIBTOOL=''
+LN_S=''
+LTLIBICONV=''
+LTLIBINTL=''
+LTLIBOBJS=''
+MACTOPBM=''
+MAKEINFO=''
+MEDCON=''
+MSGFMT=''
+MSGFMT_015=''
+MSGMERGE=''
+NEOTOPPM=''
+NOOPT_CFLAGS=''
+NOOPT_CXXFLAGS=''
+OBJEXT=''
+OpenEXR_CFLAGS=''
+OpenEXR_LIBS=''
+PACKAGE=''
+PACKAGE_BUGREPORT='ksquirrel.iv@gmail.com'
+PACKAGE_NAME='ksquirrel-libs'
+PACKAGE_STRING='ksquirrel-libs 0.8.0'
+PACKAGE_TARNAME='ksquirrel-libs'
+PACKAGE_VERSION='0.8.0'
+PATH_SEPARATOR=':'
+PI1TOPPM=''
+PI3TOPPM=''
+PICTTOPPM=''
+PKG_CONFIG=''
+POSUB=''
+RANLIB=''
+RSVG=''
+SET_MAKE=''
+SHELL='/bin/bash'
+SQ_DEVEL_FALSE=''
+SQ_DEVEL_TRUE=''
+SQ_EXR_CFLAGS=''
+SQ_EXR_LDFLAGS=''
+SQ_FT_CFLAGS=''
+SQ_FT_LDFLAGS=''
+SQ_GIFLIBS=''
+SQ_HAVE_CAMERA_FALSE=''
+SQ_HAVE_CAMERA_TRUE=''
+SQ_HAVE_DICOM_FALSE=''
+SQ_HAVE_DICOM_TRUE=''
+SQ_HAVE_DJVU_FALSE=''
+SQ_HAVE_DJVU_TRUE=''
+SQ_HAVE_DXF_FALSE=''
+SQ_HAVE_DXF_TRUE=''
+SQ_HAVE_EPS_FALSE=''
+SQ_HAVE_EPS_TRUE=''
+SQ_HAVE_FIG_FALSE=''
+SQ_HAVE_FIG_TRUE=''
+SQ_HAVE_GIF_FALSE=''
+SQ_HAVE_GIF_TRUE=''
+SQ_HAVE_IFF_FALSE=''
+SQ_HAVE_IFF_TRUE=''
+SQ_HAVE_JPEG2000_FALSE=''
+SQ_HAVE_JPEG2000_TRUE=''
+SQ_HAVE_JPEG_FALSE=''
+SQ_HAVE_JPEG_TRUE=''
+SQ_HAVE_LEAF_FALSE=''
+SQ_HAVE_LEAF_TRUE=''
+SQ_HAVE_LJPEG_FALSE=''
+SQ_HAVE_LJPEG_TRUE=''
+SQ_HAVE_MAC_FALSE=''
+SQ_HAVE_MAC_TRUE=''
+SQ_HAVE_MNG_FALSE=''
+SQ_HAVE_MNG_TRUE=''
+SQ_HAVE_NEO_FALSE=''
+SQ_HAVE_NEO_TRUE=''
+SQ_HAVE_OPENEXR_FALSE=''
+SQ_HAVE_OPENEXR_TRUE=''
+SQ_HAVE_PI1_FALSE=''
+SQ_HAVE_PI1_TRUE=''
+SQ_HAVE_PI3_FALSE=''
+SQ_HAVE_PI3_TRUE=''
+SQ_HAVE_PICT_FALSE=''
+SQ_HAVE_PICT_TRUE=''
+SQ_HAVE_SVG_FALSE=''
+SQ_HAVE_SVG_TRUE=''
+SQ_HAVE_TIFF_FALSE=''
+SQ_HAVE_TIFF_TRUE=''
+SQ_HAVE_TTF_FALSE=''
+SQ_HAVE_TTF_TRUE=''
+SQ_HAVE_UTAH_FALSE=''
+SQ_HAVE_UTAH_TRUE=''
+SQ_HAVE_WMF_FALSE=''
+SQ_HAVE_WMF_TRUE=''
+SQ_HAVE_XCF_FALSE=''
+SQ_HAVE_XCF_TRUE=''
+SQ_HAVE_XIM_FALSE=''
+SQ_HAVE_XIM_TRUE=''
+SQ_HAVE_XWD_FALSE=''
+SQ_HAVE_XWD_TRUE=''
+SQ_LOCAL_RPATH=''
+SQ_RELEASE=''
+SQ_WMF_CFLAGS=''
+SQ_WMF_LDFLAGS=''
+STRIP=''
+USE_EXCEPTIONS=''
+USE_NLS=''
+USE_RTTI=''
+UTAHTOPNM=''
+VEC2WEB=''
+VERSION=''
+WMF_CONFIG=''
+WOVERLOADED_VIRTUAL=''
+XFIG=''
+XGETTEXT=''
+XGETTEXT_015=''
+XIMTOPPM=''
+ac_ct_CC=''
+ac_ct_CXX=''
+ac_ct_F77=''
+am__fastdepCC_FALSE=''
+am__fastdepCC_TRUE=''
+am__fastdepCXX_FALSE=''
+am__fastdepCXX_TRUE=''
+am__include=''
+am__isrc=''
+am__leading_dot=''
+am__quote=''
+am__tar=''
+am__untar=''
+bindir='${exec_prefix}/bin'
+build='x86_64-pc-linux-gnu'
+build_alias='x86_64-linux-gnu'
+build_cpu='x86_64'
+build_os='linux-gnu'
+build_vendor='pc'
+datadir='${datarootdir}'
+datarootdir='${prefix}/share'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+dvidir='${docdir}'
+exec_prefix='NONE'
+host='x86_64-pc-linux-gnu'
+host_alias='x86_64-linux-gnu'
+host_cpu='x86_64'
+host_os='linux-gnu'
+host_vendor='pc'
+htmldir='${docdir}'
+includedir='${prefix}/include'
+infodir='${prefix}/share/info'
+install_sh=''
+lcms_CFLAGS=''
+lcms_LIBS=''
+libdir='${exec_prefix}/lib'
+libexecdir='${exec_prefix}/libexec'
+localedir='${datarootdir}/locale'
+localstatedir='${prefix}/var'
+mandir='${prefix}/share/man'
+mkdir_p=''
+oldincludedir='/usr/include'
+pdfdir='${docdir}'
+prefix='/opt/kde3'
+program_transform_name='s,x,x,'
+psdir='${docdir}'
+sbindir='${exec_prefix}/sbin'
+sharedstatedir='${prefix}/com'
+sysconfdir='${prefix}/etc'
+target='x86_64-pc-linux-gnu'
+target_alias=''
+target_cpu='x86_64'
+target_os='linux-gnu'
+target_vendor='pc'
+unsermake_enable_pch_FALSE=''
+unsermake_enable_pch_TRUE=''
+
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+
+#define PACKAGE_NAME "ksquirrel-libs"
+#define PACKAGE_TARNAME "ksquirrel-libs"
+#define PACKAGE_VERSION "0.8.0"
+#define PACKAGE_STRING "ksquirrel-libs 0.8.0"
+#define PACKAGE_BUGREPORT "ksquirrel.iv@gmail.com"
+
+configure: caught signal 2
+configure: exit 1
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..a39437d
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1686 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
+
+timestamp='2009-04-17'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..47af964
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,869 @@
+AC_INIT([ksquirrel-libs], [0.8.0], [ksquirrel.iv@gmail.com])
+#AC_GNU_SOURCE
+#AC_CONFIG_SRCDIR([config.h.in])
+#AM_INIT_AUTOMAKE([foreign])
+#AC_CONFIG_HEADER([config.h])
+
+AC_CONFIG_AUX_DIR([admin])
+
+AC_CANONICAL_SYSTEM
+AC_ARG_PROGRAM
+
+AM_INIT_AUTOMAKE(ksquirrel-libs, 0.8.0)
+
+AC_CHECK_COMPILERS
+AC_ENABLE_SHARED(yes)
+AC_ENABLE_STATIC(no)
+AC_PROG_LIBTOOL
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AM_PROG_CC_C_O
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+#AC_FUNC_ERROR_AT_LINE
+AC_FUNC_REALLOC
+AC_FUNC_STAT
+
+AC_CHECK_HEADER([zlib.h], [
+ AC_CHECK_LIB([z], [inflate], [
+ sq_have_zlib_ff="yes"],
+ [ AC_MSG_ERROR([zlib library not found])])
+], [ AC_MSG_ERROR([zlib header files not found])])
+
+AC_CHECK_HEADER([math.h], [
+ AC_CHECK_LIB([m], [pow], [
+ sq_have_zlib_ff="yes"],
+ [ AC_MSG_ERROR([math library not found])])
+], [ AC_MSG_ERROR([<math.h> header files not found])])
+
+sq_dev="no"
+
+AC_ARG_ENABLE(devel,
+ [AS_HELP_STRING([--enable-devel], [Enable buggy codecs (for developers only) [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_dev="yes" ;;
+ no) sq_dev="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_camera="yes"
+
+AC_ARG_ENABLE(camera,
+ [AS_HELP_STRING([--disable-camera], [don't compile camera codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_camera="yes" ;;
+ no) sq_codec_camera="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_gif="yes"
+sq_have_gif="no"
+
+AC_ARG_ENABLE(gif,
+ [AS_HELP_STRING([--disable-gif], [don't compile gif codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_gif="yes" ;;
+ no) sq_codec_gif="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_eps="yes"
+sq_have_eps="no"
+
+AC_ARG_ENABLE(eps,
+ [AS_HELP_STRING([--disable-eps], [don't compile eps codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_eps="yes" ;;
+ no) sq_codec_eps="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_svg="yes"
+sq_have_svg="no"
+
+AC_ARG_ENABLE(svg,
+ [AS_HELP_STRING([--disable-svg], [don't compile svg codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_svg="yes" ;;
+ no) sq_codec_svg="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_dicom="yes"
+sq_have_dicom="no"
+
+AC_ARG_ENABLE(dicom,
+ [AS_HELP_STRING([--disable-dicom], [don't compile dicom codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_dicom="yes" ;;
+ no) sq_codec_dicom="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_openexr="yes"
+sq_have_openexr="no"
+
+AC_ARG_ENABLE(openexr,
+ [AS_HELP_STRING([--disable-openexr], [don't compile openexr codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_openexr="yes" ;;
+ no) sq_codec_openexr="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_jpeg2000="yes"
+sq_have_jpeg2000="no"
+
+AC_ARG_ENABLE(jpeg2000,
+ [AS_HELP_STRING([--disable-jpeg2000], [don't compile jpeg2000 codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_jpeg2000="yes" ;;
+ no) sq_codec_jpeg2000="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_wmf="yes"
+sq_have_wmf="no"
+
+AC_ARG_ENABLE(wmf,
+ [AS_HELP_STRING([--disable-wmf], [don't compile wmf codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_wmf="yes" ;;
+ no) sq_codec_wmf="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_ttf="yes"
+sq_have_ttf="no"
+
+AC_ARG_ENABLE(ttf,
+ [AS_HELP_STRING([--disable-ttf], [don't compile ttf codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_ttf="yes" ;;
+ no) sq_codec_ttf="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_mng="yes"
+sq_have_mng="no"
+
+AC_ARG_ENABLE(mng,
+ [AS_HELP_STRING([--disable-mng], [don't compile mng codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_mng="yes" ;;
+ no) sq_codec_mng="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_mng="yes"
+sq_have_mng="no"
+
+AC_ARG_ENABLE(mng,
+ [AS_HELP_STRING([--disable-mng], [don't compile mng codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_mng="yes" ;;
+ no) sq_codec_mng="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_djvu="yes"
+sq_have_djvu="no"
+
+AC_ARG_ENABLE(djvu,
+ [AS_HELP_STRING([--disable-djvu], [don't compile djvu codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_djvu="yes" ;;
+ no) sq_codec_djvu="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_dxf="yes"
+sq_have_dxf="no"
+
+AC_ARG_ENABLE(dxf,
+ [AS_HELP_STRING([--disable-dxf], [don't compile dxf codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_dxf="yes" ;;
+ no) sq_codec_dxf="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_fig="yes"
+sq_have_fig="no"
+
+AC_ARG_ENABLE(fig,
+ [AS_HELP_STRING([--disable-fig], [don't compile fig codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_fig="yes" ;;
+ no) sq_codec_fig="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_xcf="yes"
+
+AC_ARG_ENABLE(xcf,
+ [AS_HELP_STRING([--disable-xcf], [don't compile xcf codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_xcf="yes" ;;
+ no) sq_codec_xcf="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+sq_codec_ljpeg="yes"
+
+AC_ARG_ENABLE(ljpeg,
+ [AS_HELP_STRING([--disable-ljpeg], [don't compile ljpeg codec [default=no]])],
+ [ case "${enableval}" in
+ yes) sq_codec_ljpeg="yes" ;;
+ no) sq_codec_ljpeg="no" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for this parameter]) ;;
+ esac]
+ )
+
+missing()
+{
+ echo
+ echo "*****************************************************"
+ echo " $2 library or headers were not found."
+ echo " $1 codec will be disabled."
+ echo " To add support of $1 codec please install"
+ echo " $2 libraries and headers."
+ echo "*****************************************************"
+ echo
+}
+
+missing_prog()
+{
+ echo
+ echo "*****************************************************"
+ echo " $2 program was not found."
+ echo " $1 codec will be disabled."
+ echo " To add support of $1 codec please install"
+ echo " $2 binary program or package."
+ echo "*****************************************************"
+ echo
+}
+
+AC_CHECK_HEADERS([ksquirrel-libs/error.h], [sq_have_ksqlibs="yes"],
+ [sq_have_ksqlibs="no"])
+
+
+# JPEG
+AC_CHECK_HEADERS([jpeglib.h], [
+ AC_CHECK_LIB([jpeg], [main], [sq_have_jpeg="yes"], [sq_have_jpeg="no" missing JPEG libjpeg])
+ ],
+ [sq_have_jpeg="no" missing JPEG libjpeg])
+
+# TIFF
+AC_CHECK_HEADERS([tiff.h], [
+ AC_CHECK_LIB([tiff], [TIFFOpen], [sq_have_tiff="yes"], [sq_have_tiff="no" missing TIFF libtiff])
+ ],
+ [sq_have_tiff="no" missing TIFF libtiff
+ ])
+
+# MNG
+
+if test $sq_codec_mng = yes; then
+AC_CHECK_HEADERS([libmng.h], [
+ AC_CHECK_LIB([mng], [mng_get_totallayers], [sq_have_mng="yes"], [sq_have_mng="no" missing MNG libmng])
+ ],
+ [sq_have_mng="no" missing MNG libmng])
+fi
+
+# SVG
+if test $sq_codec_svg = yes; then
+
+AC_PATH_PROG(RSVG, rsvg-convert)
+
+if [ test -n "$RSVG" ]; then
+ sq_have_svg="yes"
+ AC_SUBST(RSVG)
+else missing_prog SVG rsvg-convert
+fi
+
+fi
+
+# EPS
+if test $sq_codec_eps = yes; then
+
+AC_PATH_PROG(EPS2PPM, gs)
+
+if [ test -n "$EPS2PPM" ]; then
+ sq_have_eps="yes"
+ AC_SUBST(EPS2PPM)
+else missing_prog EPS gs
+fi
+
+fi
+
+# DICOM
+if test $sq_codec_dicom = yes; then
+
+AC_PATH_PROG(MEDCON, medcon)
+
+if [ test -n "$MEDCON" ]; then
+ sq_have_dicom="yes"
+ AC_SUBST(MEDCON)
+else missing_prog DICOM medcon
+fi
+
+fi
+
+if test $sq_codec_camera = yes; then
+
+PKG_CHECK_MODULES([lcms], lcms, [sq_have_cms="yes"], [sq_have_cms="no"])
+
+fi
+
+# JPEG2000
+if test $sq_codec_jpeg2000 = yes; then
+
+AC_CHECK_HEADERS([jasper/jasper.h], [
+ AC_CHECK_LIB([jasper], [jas_init], [sq_have_jpeg2000="yes"], [sq_have_jpeg2000="no" missing JPEG2000 jasper])
+ ],
+ [sq_have_jpeg2000="no" missing JPEG2000 jasper])
+
+fi
+
+# WMF
+if test $sq_codec_wmf = yes; then
+
+AC_PATH_PROG(WMF_CONFIG, libwmf-config)
+
+if [ test -n "$WMF_CONFIG" ]; then
+
+SQ_WMF_CFLAGS=`$WMF_CONFIG --cflags`
+SQ_WMF_LDFLAGS=`$WMF_CONFIG --libs`
+
+_cppflags=$CPPFLAGS
+_ldflags=$LDFLAGS
+
+CPPFLAGS="$SQ_WMF_CFLAGS $CPPFLAGS"
+LDFLAGS="$LDFLAGS $SQ_WMF_LDFLAGS"
+
+AC_CHECK_HEADERS([libwmf/types.h], [
+ AC_CHECK_LIB([wmf], [wmf_api_create], [
+ sq_have_wmf="yes"
+ AC_SUBST(SQ_WMF_CFLAGS)
+ AC_SUBST(SQ_WMF_LDFLAGS)
+ ], [sq_have_wmf="no" missing WMF libwmf])
+ ],
+ [sq_have_wmf="no" missing WMF libwmf])
+
+CPPFLAGS=$_cppflags
+LDFLAGS=$_ldflags
+
+fi
+fi
+
+# GIF
+if test $sq_codec_gif = yes; then
+
+SQ_GIFLIBS=""
+
+AC_CHECK_HEADERS([gif_lib.h], [
+ AC_CHECK_LIB([ungif], [DGifOpenFileName], [sq_have_gif="yes" SQ_GIFLIBS="-lungif"],
+ [
+ AC_CHECK_LIB([gif], [DGifOpenFileName], [sq_have_gif="yes" SQ_GIFLIBS="-lgif"], [sq_have_gif="no" missing GIF "libungif or giflib"])
+ ]
+ )
+ ],
+ [sq_have_gif="no"])
+
+AC_SUBST(SQ_GIFLIBS)
+
+fi
+
+# OPENEXR
+if test $sq_codec_openexr = yes; then
+
+PKG_CHECK_MODULES([OpenEXR], OpenEXR, [
+ SQ_EXR_CFLAGS=$OpenEXR_CFLAGS
+ SQ_EXR_LDFLAGS=$OpenEXR_LIBS
+
+ _cppflags=$CPPFLAGS
+ _ldflags=$LDFLAGS
+
+ CPPFLAGS="$SQ_EXR_CFLAGS $CPPFLAGS"
+ LDFLAGS="$LDFLAGS $SQ_EXR_LDFLAGS"
+
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ AC_CHECK_HEADERS([OpenEXR/ImfRgbaFile.h], [
+ AC_CHECK_LIB([IlmImf], [ImfInputFileName], [
+ sq_have_openexr="yes"
+ AC_SUBST(SQ_EXR_CFLAGS)
+ AC_SUBST(SQ_EXR_LDFLAGS)
+ ], [sq_have_openexr="no" missing OpenEXR libopenexr])
+ ],
+ [sq_have_openexr="no" missing OpenEXR libopenexr])
+
+ AC_LANG_RESTORE
+
+ CPPFLAGS=$_cppflags
+ LDFLAGS=$_ldflags
+ ],
+ [sq_have_openexr="no" missing OpenEXR libopenexr])
+fi
+
+_cppflags=$CPPFLAGS
+_ldflags=$LDFLAGS
+
+# TTF
+if test $sq_codec_ttf = yes; then
+
+AC_PATH_PROG(FREETYPE_CONFIG, freetype-config)
+
+if [ test -n "$FREETYPE_CONFIG" ]; then
+ freetype_cflags=`$FREETYPE_CONFIG --cflags`
+ freetype_libs=`$FREETYPE_CONFIG --libs`
+
+ CPPFLAGS="$freetype_cflags $CPPFLAGS"
+ LDFLAGS="$LDFLAGS $freetype_libs"
+
+ AC_CHECK_HEADER([ft2build.h], [
+ AC_CHECK_HEADER([freetype/ftbitmap.h], [
+ AC_CHECK_LIB([freetype], [FTC_ImageCache_New], [
+ AC_CHECK_LIB([freetype], [FTC_SBitCache_New], [
+ AC_CHECK_LIB([freetype], [FTC_CMapCache_New], [
+ AC_CHECK_LIB([freetype], [FTC_Manager_New], [
+ AC_CHECK_LIB([freetype], [FT_Get_Kerning], [
+ AC_CHECK_LIB([freetype], [FT_Get_Track_Kerning], [
+
+ SQ_FT_LDFLAGS="$freetype_libs"
+ SQ_FT_CFLAGS="$freetype_cflags"
+ sq_have_ttf="yes"
+ AC_SUBST(SQ_FT_CFLAGS)
+ AC_SUBST(SQ_FT_LDFLAGS)
+
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+ ],[ sq_have_ttf="no" missing TTF freetype])
+fi
+
+CPPFLAGS=$_cppflags
+LDFLAGS=$_ldflags
+
+fi
+
+if test $sq_codec_djvu = yes; then
+
+AC_PATH_PROG(DJVU, ddjvu)
+
+if [ test -n "$DJVU" ]; then
+ sq_have_djvu="yes"
+ AC_SUBST(DJVU)
+else missing_prog DJVU ddjvu
+fi
+
+fi
+
+if test $sq_codec_fig = yes; then
+
+AC_PATH_PROG(XFIG, fig2dev)
+
+if [ test -n "$XFIG" ]; then
+ sq_have_fig="yes"
+ AC_SUBST(XFIG)
+else missing_prog XFIG fig2dev
+fi
+
+fi
+
+if test $sq_codec_dxf = yes; then
+
+AC_PATH_PROG(VEC2WEB, vec2web)
+
+if [ test -n "$VEC2WEB" ]; then
+ sq_have_dxf="yes"
+ AC_SUBST(VEC2WEB)
+else missing_prog DXF vec2web
+fi
+
+fi
+
+AC_CHECK_HEADERS([X11/XWDFile.h], [sq_have_xwd="yes"], [sq_have_xwd="no" missing XWD])
+
+############### NetPBM binaries ###############
+
+AC_MSG_CHECKING([netpbm binary programs])
+$ECHO
+
+sq_codec_neo="yes"
+sq_have_neo="no"
+if test $sq_codec_neo = yes; then
+ AC_PATH_PROG(NEOTOPPM, neotoppm)
+ if [ test -n "$NEOTOPPM" ]; then sq_have_neo="yes" AC_SUBST(NEOTOPPM)
+ else missing_prog NEO netpbm
+ fi
+fi
+
+sq_codec_leaf="yes"
+sq_have_leaf="no"
+if test $sq_codec_leaf = yes; then
+ AC_PATH_PROG(LEAFTOPPM, leaftoppm)
+ if [ test -n "$LEAFTOPPM" ]; then sq_have_leaf="yes" AC_SUBST(LEAFTOPPM)
+ else missing_prog LEAF netpbm
+ fi
+fi
+
+sq_codec_pi1="yes"
+sq_have_pi1="no"
+if test $sq_codec_pi1 = yes; then
+ AC_PATH_PROG(PI1TOPPM, pi1toppm)
+ if [ test -n "$PI1TOPPM" ]; then sq_have_pi1="yes" AC_SUBST(PI1TOPPM)
+ else missing_prog PI1 netpbm
+ fi
+fi
+
+sq_codec_pi3="yes"
+sq_have_pi3="no"
+if test $sq_codec_pi3 = yes; then
+ AC_PATH_PROG(PI3TOPPM, pi3topbm)
+ if [ test -n "$PI3TOPPM" ]; then sq_have_pi3="yes" AC_SUBST(PI3TOPPM)
+ else missing_prog PI3 netpbm
+ fi
+fi
+
+sq_codec_xim="yes"
+sq_have_xim="no"
+if test $sq_codec_xim = yes; then
+ AC_PATH_PROG(XIMTOPPM, ximtoppm)
+ if [ test -n "$XIMTOPPM" ]; then sq_have_xim="yes" AC_SUBST(XIMTOPPM)
+ else missing_prog XIM netpbm
+ fi
+fi
+
+sq_codec_utah="yes"
+sq_have_utah="no"
+if test $sq_codec_utah = yes; then
+ AC_PATH_PROG(UTAHTOPNM, rletopnm)
+ if [ test -n "$UTAHTOPNM" ]; then sq_have_utah="yes" AC_SUBST(UTAHTOPNM)
+ else missing_prog UTAH netpbm
+ fi
+fi
+
+sq_codec_pict="yes"
+sq_have_pict="no"
+if test $sq_codec_pict = yes; then
+ AC_PATH_PROG(PICTTOPPM, picttoppm)
+ if [ test -n "$PICTTOPPM" ]; then sq_have_pict="yes" AC_SUBST(PICTTOPPM)
+ else missing_prog PICT netpbm
+ fi
+fi
+
+sq_codec_mac="yes"
+sq_have_mac="no"
+if test $sq_codec_mac = yes; then
+ AC_PATH_PROG(MACTOPBM, macptopbm)
+ if [ test -n "$MACTOPBM" ]; then sq_have_mac="yes" AC_SUBST(MACTOPBM)
+ else missing_prog MAC netpbm
+ fi
+fi
+
+sq_codec_iff="yes"
+sq_have_iff="no"
+if test $sq_codec_iff = yes; then
+ AC_PATH_PROG(ILBMTOPPM, ilbmtoppm)
+ if [ test -n "$ILBMTOPPM" ]; then sq_have_iff="yes" AC_SUBST(ILBMTOPPM)
+ else missing_prog IFF netpbm
+ fi
+fi
+
+#################################################
+
+
+SQ_LOCAL_RPATH="-L../ksquirrel-libs -lksquirrel-libs"
+AC_SUBST(SQ_LOCAL_RPATH)
+SQ_RELEASE="-version-info 8:0:8"
+AC_SUBST(SQ_RELEASE)
+
+################### for xcf codec ##############
+
+AC_C_INLINE
+
+if test $sq_codec_xcf = yes; then
+
+case $GCC::$CFLAGS in yes::*-Wall* ) ;;
+ yes::*) CFLAGS="$CFLAGS -Wall" ;;
+esac
+case $GCC::$CFLAGS in *-g* | *omit-frame-pointer* ) ;;
+ yes::*) CFLAGS="$CFLAGS -fomit-frame-pointer" ;;
+esac
+
+AC_C_BIGENDIAN
+
+case $host_cpu in i?86 | x86_64 | powerpc)
+ AC_DEFINE(CAN_DO_UNALIGNED_WORDS,1,
+ [Define for CPUs that can read unaligned words without traps or faults])
+esac
+
+AC_CHECK_HEADERS(inttypes.h netinet/in.h arpa/inet.h getopt.h)
+
+AC_CHECK_FUNCS(getopt_long strcasecmp)
+AC_FUNC_MMAP
+AM_GNU_GETTEXT(external)
+AM_ICONV
+
+fi
+
+################################################
+
+AC_CONFIG_FILES([
+Makefile
+doc/Makefile
+doc/html/Makefile
+doc/sources/Makefile
+kernel/Makefile
+kernel/kls_bmp/Makefile
+kernel/kls_dds/Makefile
+kernel/kls_gif/Makefile
+kernel/kls_pix/Makefile
+kernel/kls_xbm/Makefile
+kernel/kls_xpm/Makefile
+kernel/kls_tga/Makefile
+kernel/kls_sgi/Makefile
+kernel/kls_ras/Makefile
+kernel/kls_pnm/Makefile
+kernel/kls_pcx/Makefile
+kernel/kls_ico/Makefile
+kernel/kls_xcur/Makefile
+kernel/kls_psd/Makefile
+kernel/kls_fli/Makefile
+kernel/kls_cut/Makefile
+kernel/kls_rawrgb/Makefile
+kernel/kls_wbmp/Makefile
+kernel/kls_sun/Makefile
+kernel/kls_jpeg2000/Makefile
+kernel/kls_openexr/Makefile
+kernel/kls_koala/Makefile
+kernel/kls_wal/Makefile
+kernel/kls_mdl/Makefile
+kernel/kls_hdr/Makefile
+kernel/kls_sct/Makefile
+kernel/kls_lif/Makefile
+kernel/kls_mtv/Makefile
+kernel/kls_avs/Makefile
+kernel/kls_msp/Makefile
+kernel/kls_dicom/Makefile
+kernel/kls_dicom/ksquirrel-libs-dicom2png
+kernel/kls_svg/Makefile
+kernel/kls_svg/ksquirrel-libs-svg2png
+kernel/kls_wmf/Makefile
+kernel/kls_png/ksquirrel-libs-png/Makefile
+kernel/kls_png/Makefile
+kernel/kls_jpeg/Makefile
+kernel/kls_xwd/Makefile
+kernel/kls_tiff/Makefile
+kernel/kls_camera/Makefile
+kernel/kls_camera/ksquirrel-libs-camera2ppm
+kernel/kls_pxr/Makefile
+kernel/kls_ttf/Makefile
+kernel/kls_ttf/ftview/Makefile
+kernel/kls_mng/Makefile
+kernel/kls_jbig/libjbig/Makefile
+kernel/kls_jbig/Makefile
+kernel/kls_djvu/Makefile
+kernel/kls_dxf/Makefile
+kernel/kls_xcf/Makefile
+kernel/kls_xcf/xcf2pnm/Makefile
+kernel/kls_fig/ksquirrel-libs-fig2ppm
+kernel/kls_fig/Makefile
+kernel/kls_mac/ksquirrel-libs-mac2ppm
+kernel/kls_mac/Makefile
+kernel/kls_iff/ksquirrel-libs-iff2ppm
+kernel/kls_iff/Makefile
+kernel/kls_neo/ksquirrel-libs-neo2ppm
+kernel/kls_neo/Makefile
+kernel/kls_pi1/ksquirrel-libs-pi12ppm
+kernel/kls_pi1/Makefile
+kernel/kls_pi3/ksquirrel-libs-pi32ppm
+kernel/kls_pi3/Makefile
+kernel/kls_xim/ksquirrel-libs-xim2ppm
+kernel/kls_xim/Makefile
+kernel/kls_leaf/ksquirrel-libs-leaf2ppm
+kernel/kls_leaf/Makefile
+kernel/kls_utah/ksquirrel-libs-utah2ppm
+kernel/kls_utah/Makefile
+kernel/kls_pict/ksquirrel-libs-pict2ppm
+kernel/kls_pict/Makefile
+kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s
+kernel/kls_ljpeg/ljpeg2ppm/Makefile
+kernel/kls_ljpeg/Makefile
+kernel/kls_eps/Makefile
+kernel/kls_psp/Makefile
+kernel/ksquirrel-libs/Makefile
+ksquirrellibs.pc
+])
+
+
+AM_CONDITIONAL(SQ_DEVEL, [ test $sq_dev = yes ])
+
+AM_CONDITIONAL(CAMERA_NO_CMS, [ test $sq_have_cms = no ])
+AM_CONDITIONAL(CAMERA_NO_JPEG, [ test $sq_have_jpeg = no ])
+AM_CONDITIONAL(SQ_HAVE_JPEG, [ test $sq_have_jpeg = yes ])
+AM_CONDITIONAL(SQ_HAVE_XWD, [ test $sq_have_xwd = yes ])
+AM_CONDITIONAL(SQ_HAVE_TIFF, [ test $sq_have_tiff = yes ])
+AM_CONDITIONAL(SQ_HAVE_EPS, [ test $sq_have_eps = yes ])
+
+AM_CONDITIONAL(SQ_HAVE_CAMERA, [ test $sq_codec_camera = yes ])
+AM_CONDITIONAL(SQ_HAVE_SVG, [ test $sq_codec_svg = yes -a $sq_have_svg = yes ])
+AM_CONDITIONAL(SQ_HAVE_DICOM, [ test $sq_codec_dicom = yes -a $sq_have_dicom = yes ])
+AM_CONDITIONAL(SQ_HAVE_WMF, [ test $sq_codec_wmf = yes -a $sq_have_wmf = yes ])
+AM_CONDITIONAL(SQ_HAVE_JPEG2000,[ test $sq_codec_jpeg2000 = yes -a $sq_have_jpeg2000 = yes ])
+AM_CONDITIONAL(SQ_HAVE_OPENEXR, [ test $sq_codec_openexr = yes -a $sq_have_openexr = yes ])
+AM_CONDITIONAL(SQ_HAVE_GIF, [ test $sq_codec_gif = yes -a $sq_have_gif = yes ])
+AM_CONDITIONAL(SQ_HAVE_TTF, [ test $sq_codec_ttf = yes -a $sq_have_ttf = yes ])
+AM_CONDITIONAL(SQ_HAVE_MNG, [ test $sq_codec_mng = yes -a $sq_have_mng = yes ])
+AM_CONDITIONAL(SQ_HAVE_DJVU, [ test $sq_codec_djvu = yes -a $sq_have_djvu = yes ])
+AM_CONDITIONAL(SQ_HAVE_DXF, [ test $sq_codec_dxf = yes -a $sq_have_dxf = yes ])
+AM_CONDITIONAL(SQ_HAVE_FIG, [ test $sq_codec_fig = yes -a $sq_have_fig = yes ])
+AM_CONDITIONAL(SQ_HAVE_XCF, [ test $sq_codec_xcf = yes ])
+AM_CONDITIONAL(SQ_HAVE_LJPEG, [ test $sq_codec_ljpeg = yes ])
+
+# NetPBM
+AM_CONDITIONAL(SQ_HAVE_NEO, [ test $sq_have_neo = yes ])
+AM_CONDITIONAL(SQ_HAVE_XIM, [ test $sq_have_xim = yes ])
+AM_CONDITIONAL(SQ_HAVE_PI1, [ test $sq_have_pi1 = yes ])
+AM_CONDITIONAL(SQ_HAVE_PI3, [ test $sq_have_pi3 = yes ])
+AM_CONDITIONAL(SQ_HAVE_UTAH, [ test $sq_have_utah = yes ])
+AM_CONDITIONAL(SQ_HAVE_LEAF, [ test $sq_have_leaf = yes ])
+AM_CONDITIONAL(SQ_HAVE_PICT, [ test $sq_have_pict = yes ])
+AM_CONDITIONAL(SQ_HAVE_MAC, [ test $sq_have_mac = yes ])
+AM_CONDITIONAL(SQ_HAVE_IFF, [ test $sq_have_iff = yes ])
+
+AC_OUTPUT
+
+echo "
+KSquirrel-libs configuration:
+-----------------------------
+ Source code location: ${srcdir}
+ ksquirrel-libs version: ${VERSION}
+ C++ Compiler: ${CXX}
+ C++ Compiler flags: ${CXXFLAGS}
+ Local ldflags: ${SQ_LOCAL_RPATH}
+
+Installation options:
+---------------------
+ libdir: ${libdir} ${libdir_warn}
+
+Libraries:
+----------"
+
+sq_enabled=""
+sq_disabled=""
+sq_manual=""
+sq_total="31"
+sq_devel=""
+sq_devel_message=""
+
+if test $sq_have_jpeg = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled jpeg `; else sq_disabled=`echo -n $sq_disabled jpeg `; fi
+if test $sq_have_xwd = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled xwd `; else sq_disabled=`echo -n $sq_disabled xwd `; fi
+if test $sq_have_tiff = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled tiff `; else sq_disabled=`echo -n $sq_disabled tiff `; fi
+if test $sq_codec_camera = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled camera `; else sq_disabled=`echo -n $sq_disabled camera `;fi
+if test $sq_codec_camera = yes; then sq_camera_sett="Additional CAMERA settings: [LCMS: $sq_have_cms, JPEG: $sq_have_jpeg]";fi
+if test $sq_have_wmf = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled wmf `; else sq_disabled=`echo -n $sq_disabled wmf `; fi
+if test $sq_have_svg = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled svg `; else sq_disabled=`echo -n $sq_disabled svg `; fi
+if test $sq_have_dicom = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled dicom `; else sq_disabled=`echo -n $sq_disabled dicom `; fi
+if test $sq_have_openexr = yes;then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled openexr `;else sq_disabled=`echo -n $sq_disabled openexr `;fi
+if test $sq_have_ttf = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled ttf `; else sq_disabled=`echo -n $sq_disabled ttf `; fi
+if test $sq_have_mng = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled mng `; else sq_disabled=`echo -n $sq_disabled mng `; fi
+if test $sq_have_gif = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled gif `; else sq_disabled=`echo -n $sq_disabled gif `; fi
+if test $sq_have_djvu = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled djvu `; else sq_disabled=`echo -n $sq_disabled djvu `; fi
+if test $sq_have_dxf = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled dxf `; else sq_disabled=`echo -n $sq_disabled dxf `; fi
+if test $sq_have_fig = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled fig `; else sq_disabled=`echo -n $sq_disabled fig `; fi
+if test $sq_codec_xcf = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled xcf `; else sq_disabled=`echo -n $sq_disabled xcf `; fi
+if test $sq_codec_eps = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled eps `; else sq_disabled=`echo -n $sq_disabled eps `; fi
+
+if test $sq_have_neo = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled neo `; else sq_disabled=`echo -n $sq_disabled neo `; fi
+if test $sq_have_pi1 = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled pi1 `; else sq_disabled=`echo -n $sq_disabled pi1 `; fi
+if test $sq_have_pi3 = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled pi3 `; else sq_disabled=`echo -n $sq_disabled pi3 `; fi
+if test $sq_have_utah = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled utah `; else sq_disabled=`echo -n $sq_disabled utah `; fi
+if test $sq_have_xim = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled xim `; else sq_disabled=`echo -n $sq_disabled xim `; fi
+if test $sq_have_leaf = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled leaf `; else sq_disabled=`echo -n $sq_disabled leaf `; fi
+if test $sq_have_pict = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled pict `; else sq_disabled=`echo -n $sq_disabled pict `; fi
+if test $sq_have_iff = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled iff `; else sq_disabled=`echo -n $sq_disabled iff `; fi
+if test $sq_have_mac = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled mac `; else sq_disabled=`echo -n $sq_disabled mac `; fi
+if test $sq_codec_ljpeg = yes; then sq_total=`expr $sq_total + 1` && sq_enabled=`echo -n $sq_enabled ljpeg `; else sq_disabled=`echo -n $sq_disabled ljpeg `; fi
+
+if test $sq_dev = yes; then sq_total=`expr $sq_total + 1`; else sq_devel="msp" && sq_devel_message="(use --enable-devel to enable these codecs)"; fi
+
+if test $sq_codec_camera = no; then sq_manual=`echo -n $sq_manual camera`; fi
+if test $sq_codec_gif = no; then sq_manual=`echo -n $sq_manual gif`; fi
+if test $sq_codec_svg = no; then sq_manual=`echo -n $sq_manual svg`; fi
+if test $sq_codec_dicom = no; then sq_manual=`echo -n $sq_manual dicom`; fi
+if test $sq_codec_wmf = no; then sq_manual=`echo -n $sq_manual wmf`; fi
+if test $sq_codec_openexr = no; then sq_manual=`echo -n $sq_manual openexr`; fi
+if test $sq_codec_jpeg2000 = no; then sq_manual=`echo -n $sq_manual jpeg2000`; fi
+if test $sq_codec_ttf = no; then sq_manual=`echo -n $sq_manual ttf`; fi
+if test $sq_codec_mng = no; then sq_manual=`echo -n $sq_manual mng`; fi
+if test $sq_codec_djvu = no; then sq_manual=`echo -n $sq_manual djvu`; fi
+if test $sq_codec_dxf = no; then sq_manual=`echo -n $sq_manual dxf`; fi
+if test $sq_codec_xcf = no; then sq_manual=`echo -n $sq_manual xcf`; fi
+if test $sq_codec_ljpeg = no; then sq_manual=`echo -n $sq_manual ljpeg`; fi
+
+# old version of ksquirrel-libs installed
+sq_have_ksqlibs_msg=""
+if test $sq_have_ksqlibs = yes;
+then sq_have_ksqlibs_msg="
+************************************************
+******************** WARNING *******************
+************************************************
+
+ It seemed that old version of ksquirrel-libs
+ is installed on your system. It is HIGHLY
+ recommended to remove old version (headers
+ and libraries) before installing new one.
+
+************************************************
+";
+fi
+
+echo "
+ Total enabled codecs : $sq_total
+ Optional formats, enabled : $sq_enabled
+ Optional formats, disabled: $sq_disabled
+ $sq_camera_sett
+ Manually disabled : $sq_manual
+ Disabled as buggy : $sq_devel $sq_devel_message
+ $sq_have_ksqlibs_msg
+Now run 'make' to compile ksquirrel-libs
+ "
diff --git a/configure.gnu b/configure.gnu
new file mode 100755
index 0000000..1d743d0
--- /dev/null
+++ b/configure.gnu
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+#par="--exec-prefix=/usr --prefix=/usr --libdir=/usr/lib/ksquirrel"
+par="--disable-rpath --prefix=/usr"
+
+echo "*** Doing configure $* $par ..."
+
+./configure $* $par
diff --git a/description-pak b/description-pak
new file mode 100644
index 0000000..2d53232
--- /dev/null
+++ b/description-pak
@@ -0,0 +1 @@
+Set of image codecs for KSquirrel
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..2755823
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sources html \ No newline at end of file
diff --git a/doc/html/Makefile.am b/doc/html/Makefile.am
new file mode 100644
index 0000000..b0951e0
--- /dev/null
+++ b/doc/html/Makefile.am
@@ -0,0 +1,22 @@
+EXTRA_DIST = belka_bkgr.gif how_to_build_c++.png ksquirrel-libs-olibs1.html bits.html index.html ksquirrel-libs-olibs2.html Makefile.am development-highlev.html ksquirrel-libs-about.html ksquirrel-libs-olibs2.html how_to_build_arrow.png ksquirrel-libs-fio.html ksquirrel-libs-olibs3.html how_to_build_codec.png ksquirrel-libs-olibs.html styles.css how_to_build_c.png ksquirrel-libs-metainfo.html ksquirrel-libs-struct.html
+
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)
+ $(INSTALL_DATA) index.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/index.html
+ $(INSTALL_DATA) bits.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/bits.html
+ $(INSTALL_DATA) development-highlev.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/development-highlev.html
+ $(INSTALL_DATA) ksquirrel-libs-about.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-about.html
+ $(INSTALL_DATA) ksquirrel-libs-fio.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-fio.html
+ $(INSTALL_DATA) ksquirrel-libs-metainfo.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-metainfo.html
+ $(INSTALL_DATA) ksquirrel-libs-struct.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-struct.html
+ $(INSTALL_DATA) ksquirrel-libs-olibs.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-olibs.html
+ $(INSTALL_DATA) ksquirrel-libs-olibs1.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-olibs1.html
+ $(INSTALL_DATA) ksquirrel-libs-olibs2.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-olibs2.html
+ $(INSTALL_DATA) ksquirrel-libs-olibs3.html $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/ksquirrel-libs-olibs3.html
+ $(INSTALL_DATA) styles.css $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/styles.css
+ $(INSTALL_DATA) belka_bkgr.gif $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/belka_bkgr.gif
+ $(INSTALL_DATA) how_to_build_c.png $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/how_to_build_c.png
+ $(INSTALL_DATA) how_to_build_c++.png $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/how_to_build_c++.png
+ $(INSTALL_DATA) how_to_build_codec.png $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/how_to_build_codec.png
+ $(INSTALL_DATA) how_to_build_arrow.png $(DESTDIR)$(datadir)/doc/ksquirrel-libs/$(PACKAGE_VERSION)/how_to_build_arrow.png
diff --git a/doc/html/belka_bkgr.gif b/doc/html/belka_bkgr.gif
new file mode 100644
index 0000000..75f5cb8
--- /dev/null
+++ b/doc/html/belka_bkgr.gif
Binary files differ
diff --git a/doc/html/bits.html b/doc/html/bits.html
new file mode 100644
index 0000000..d889727
--- /dev/null
+++ b/doc/html/bits.html
@@ -0,0 +1,44 @@
+<pre>
+#include &#60;stdio.h&#62;
+#include &#60;sys/types.h&#62;
+#include &#60;sys/stat.h&#62;
+#include &#60;unistd.h&#62;
+
+int main(int argc, char **argv)
+{
+ int i;
+ for(i = 1;i &#60; argc;i++)
+ {
+ FILE *f = fopen(argv[i], "rb");
+ char c;
+ struct stat buf;
+
+ if(!f)
+ {
+ fprintf(stderr, "Can't open file.\n");
+ return 255;
+ }
+
+ int s = 0, sz;
+ stat(argv[i], &buf);
+
+ sz = buf.st_size;
+
+ printf("%s\nstd::string fmt_codec::fmt_pixmap()\n{\n\treturn std::string(\"", argv[i]);
+
+ while(s++ &#60; sz-1)
+ {
+ fread(&c, 1, 1, f);
+ printf("%u,", (unsigned char)c);
+ }
+
+ fread(&c, 1, 1, f);
+ printf("%u", (unsigned char)c);
+
+ printf("\");\n}\n\n");
+ fclose(f);
+ }
+
+ return 0;
+}
+</pre> \ No newline at end of file
diff --git a/doc/html/development-highlev.html b/doc/html/development-highlev.html
new file mode 100644
index 0000000..6174f5c
--- /dev/null
+++ b/doc/html/development-highlev.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
+
+ <link rel='stylesheet' href='styles.css' type='text/css'>
+</head>
+
+<body>
+
+When SQ_LibraryHandler loaded all found libraries, KSquirrel obtains the ability to decode any supported image format.
+Here is a sample code to decode some image with library. Error handling is turned <b>off</b>. You can find real examples in
+source distribution of ksquirrel-libs.
+
+<p><b><u>Sample</u></b>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+<tbody>
+<tr>
+<td valign="top" bgcolor="#CCCCCC">
+<pre>
+ int i, j, current = 0;
+ fmt_info finfo;
+ RGBA *image = NULL, *scan;
+ fmt_codec_base *codeK;
+
+ QString file = "/home/krasu/animation1.gif";
+
+ <b>Determine the library and codec</b>
+ codeK = SQ_LibraryHandler::instance()->libraryForFile(file)->codec;
+
+ <b>Init: open file, etc.</b>
+ codeK->read_init(file.ascii());
+
+ while(true)
+ {
+ i = codeK->read_next();
+
+ <b>Break, if we've decoded all available images in file</b>
+ if(i == SQE_NOTOK)
+ break;
+
+ <b>Obtain the latest information (current image dimensions, etc.)</b>
+ finfo = codeK->information();
+
+ <b>realloc memory for new image</b>
+ image = (RGBA *)realloc(image, finfo.image[current].w * finfo.image[current].h * sizeof(RGBA));
+
+ <b>fill with white color (RGBA(255,255,255,255))</b>
+ memset(image, 255, finfo.image[current].w * finfo.image[current].h * sizeof(RGBA));
+
+ for(int pass = 0;pass &#60; finfo.image[current].passes;pass++)
+ {
+ codeK->read_next_pass();
+
+ for(j = 0;j &#60; finfo.image[current].h;j++)
+ {
+ scan = image + j * finfo.image[current].w;
+ codeK->read_scanline(scan);
+ }
+ }
+
+ <b>Do something with decoded image here.
+ ...</b>
+
+ current++;
+ }
+
+ codeK->read_close();
+
+ free(image);
+
+</pre>
+</td>
+</tr>
+</tbody>
+</table>
+
+</body>
+</html>
diff --git a/doc/html/how_to_build_arrow.png b/doc/html/how_to_build_arrow.png
new file mode 100644
index 0000000..ff94733
--- /dev/null
+++ b/doc/html/how_to_build_arrow.png
Binary files differ
diff --git a/doc/html/how_to_build_c++.png b/doc/html/how_to_build_c++.png
new file mode 100644
index 0000000..3050def
--- /dev/null
+++ b/doc/html/how_to_build_c++.png
Binary files differ
diff --git a/doc/html/how_to_build_c.png b/doc/html/how_to_build_c.png
new file mode 100644
index 0000000..2610b60
--- /dev/null
+++ b/doc/html/how_to_build_c.png
Binary files differ
diff --git a/doc/html/how_to_build_codec.png b/doc/html/how_to_build_codec.png
new file mode 100644
index 0000000..2348108
--- /dev/null
+++ b/doc/html/how_to_build_codec.png
Binary files differ
diff --git a/doc/html/index.html b/doc/html/index.html
new file mode 100644
index 0000000..5726395
--- /dev/null
+++ b/doc/html/index.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
+
+ <link rel='stylesheet' href='styles.css' type='text/css'>
+</head>
+
+<body>
+
+<p>If you want to help to develop this project, please contact me by <a href='mailto:ksquirrel@tut.by'>e-mail</a>.
+<p>Here you can find various information, concerning development KSquirrel and libraries ksquirrel-libs.
+<p>All information listed below is valid for <b>v0.6.0-pre3</b> or later.
+
+<p><a href='ksquirrel-libs-about.html'>About ksquirrel-libs</a>
+<p><a href='development-highlev.html'>How KSquirrel uses ksquirrel-libs</a>
+<p><a href='ksquirrel-libs-olibs.html'>How to build libraries</a>
+<p><a href='ksquirrel-libs-struct.html'>About typedefs in ksquirrel-libs</a>
+<p><a href='ksquirrel-libs-metainfo.html'>Using metainfo mechanism</a>
+<p><a href='ksquirrel-libs-fio.html'>Internal file i/o</a>
+
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-about.html b/doc/html/ksquirrel-libs-about.html
new file mode 100644
index 0000000..16668d7
--- /dev/null
+++ b/doc/html/ksquirrel-libs-about.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+<p>ksquirrel-libs can be described in following terms:
+
+<p><ul>
+<li>ksquirrel-libs is a set of codecs for the browser of images KSquirrel.
+<li>format of libraries is very simple, so you can write the codec necessary to you.
+<li>you can use ksquirrel-libs in your program - simply realize the mechanism, allowing to manipulate a set of such libraries (like SQ_LibraryHandler class in KSquirrel).
+<li>each codec has a strictly defined set of functions which provide the interface of library.
+<li>from the version 0.6.0-pre1 codecs are written on C++.
+<li>from the point of view of C++ all codecs absolutely identical - they differ only with contents of methods.
+</ul>
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-fio.html b/doc/html/ksquirrel-libs-fio.html
new file mode 100644
index 0000000..2ead0b7
--- /dev/null
+++ b/doc/html/ksquirrel-libs-fio.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+For reading and writing data I use the following classes, inherited from ifstream and ofstream.
+
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+<tbody>
+<tr>
+<td valign="top" bgcolor="#CCCCCC">
+<pre>
+<b>Class for reading binary data</b>
+class ifstreamK : public ifstream
+{
+ public:
+ ifstreamK();
+
+ <b>Read 'size' bytes of binary data and store it into 'data'.
+ Returns true if reading was successful, and false otherwise</b>
+ bool readK(void *data, int size);
+
+ <b>Read string from file</b>
+ bool getS(char *, const int);
+
+ <b>Read ascii hex value from file (like "0xFFFF00")</b>
+ bool readCHex(u32 &amp;hex);
+
+ <b>big-endian-oriented reading</b>
+ bool be_getchar(u8 *c);
+ bool be_getshort(u16 *s);
+ bool be_getlong(u32 *l);
+};
+
+<b>Class for writing binary data</b>
+class ofstreamK : public ofstream
+{
+ public:
+ ofstreamK();
+
+ bool writeK(void *data, int size);
+};
+</pre>
+</td>
+</tr>
+</tbody>
+</table>
+
+<b><u>Examples</u></b>
+
+<ul>
+<li> Read structure from binary file
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+ typedef struct
+ {
+ int a;
+ short b;
+ char c;
+
+ }Data;
+
+ ...
+
+ class::class()
+ {
+ fs.open("file.bin", ios::in | ios::binary);
+ }
+
+ int class::readstruct(Data *s)
+ {
+ bool b = fs.readK(s, sizeof(Data));
+
+ cerr &#60;&#60; "Reading " &#60;&#60; (b ? "OK" : "Failed") &#60;&#60; endl;
+ }
+
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<br><br>
+<li> Write structure to binary file
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+ typedef struct
+ {
+ int a;
+ short b;
+ char c;
+
+ }Data;
+
+ ...
+
+ class::class()
+ {
+ fs.open("file.bin", ios::out | ios::binary);
+ }
+
+ int class::writestruct(Data *s)
+ {
+ bool b = fs.writeK(s, sizeof(Data));
+
+ cerr &#60;&#60; "Writing " &#60;&#60; (b ? "OK" : "Failed") &#60;&#60; endl;
+ }
+
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<br>
+
+<b><u>Note:</u></b> remember, that reading and writing structures in binary mode is not doog idea. This is just example. See <a href='http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7'>http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7</a> and <a href='http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3'>http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3</a> for more.
+
+<br><br>
+
+</ul>
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-metainfo.html b/doc/html/ksquirrel-libs-metainfo.html
new file mode 100644
index 0000000..2f5cf4d
--- /dev/null
+++ b/doc/html/ksquirrel-libs-metainfo.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+<p>For support of a metainformation, saved together with some images, in ksquirrel-libs exists the special
+structure similar to map. Support of a metainformation COMPLETELY lays down on library i.e.
+if in image file there are any collateral data, but library ignores it,
+KSquirrel (as well as any other viewer on the basis of ksquirrel-libs) will not display it in
+"Image Properties" dialog.
+
+<p>At present EXIF the information is not supported yet, but in v0.6.0 it possibly will be realized.
+<p>Formally work with a metainformation looks so: [read some information from a file] => [group it] => [keep in object 'finfo']. Further you can see an example of the elementary reading and preservation of a metainformation.
+<p>You should read metainfo in <b>fmt_read_next()</b> and store it in <b>finfo.meta</b>.
+
+<p>
+<b><u>Example</u></b>
+
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+<tbody>
+<tr>
+<td valign="top" bgcolor="#CCCCCC">
+<pre>
+ <b>Read information from file</b>
+ frs.readK(str, 255);
+
+ <b>Don't forget to insert '\0', if necessary</b>
+ str[255] = '\0';
+
+ fmt_metaentry mt;
+
+ <b>Setup group name. It can be "JPEG "COM" Marker", "PNG key",
+ "SGI Image Name", or any other you want.</b>
+ mt.group = "Group name";
+
+ <b>Copy information</b>
+ mt.data = str;
+
+ <b>insert new metaentry</b>
+ finfo.meta.push_back(mt);
+</pre>
+</td>
+</tr>
+</tbody>
+</table>
+
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-olibs.html b/doc/html/ksquirrel-libs-olibs.html
new file mode 100644
index 0000000..915617b
--- /dev/null
+++ b/doc/html/ksquirrel-libs-olibs.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+Let's now learn how to create regular C or C++ library, and how to create a new decoder for KSquirrel. You can find sources of all examples in ksquirrel-libs/doc/sources.
+
+<p>
+
+<center>
+<table>
+ <tr><td><a href="ksquirrel-libs-olibs1.html"><img src="how_to_build_c.png"></a></td></tr>
+ <tr><td align=center> <img src="how_to_build_arrow.png"></td></tr>
+ <tr><td><a href="ksquirrel-libs-olibs2.html"><img src="how_to_build_c++.png"></a></td></tr>
+ <tr><td align=center><img src="how_to_build_arrow.png"></td></tr>
+ <tr><td><a href="ksquirrel-libs-olibs3.html"><img src="how_to_build_codec.png"></a></td></tr>
+</table>
+</center>
+
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-olibs1.html b/doc/html/ksquirrel-libs-olibs1.html
new file mode 100644
index 0000000..1965e7d
--- /dev/null
+++ b/doc/html/ksquirrel-libs-olibs1.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+<ul>
+<li>First, write regular C program (without main()):
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+ const char* fmt_info()
+ {
+ return "It is really cool format!";
+ }
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>Compile it
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+ # gcc -O2 -fPIC -c module.c
+ # gcc -shared -o module.so module.o
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>Let's write a simple test
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+ #include &#60;unistd.h&#62;
+ #include &#60;string.h&#62;
+ #include &#60;errno.h&#62;
+ #include &#60;dlfcn.h&#62;
+
+ #define PATH_LENGTH 256
+
+ int main(int argc, char * argv[])
+ {
+ char path[PATH_LENGTH], *msg = NULL;
+ const char* (*fmt)();
+ void *module;
+
+ getcwd(path, PATH_LENGTH);
+ strcat(path, "/");
+ strcat(path, "module.so");
+
+ /* Load module */
+ module = dlopen(path, RTLD_NOW);
+
+ /* Error ! */
+ if(!module)
+ {
+ msg = dlerror();
+
+ if(msg != NULL)
+ {
+ dlclose(module);
+ exit(1);
+ }
+ }
+
+ /* Try to resolve function "fmt_info()" */
+ fmt = dlsym(module, "fmt_info");
+
+ msg = dlerror();
+
+ if(msg != NULL)
+ {
+ perror(msg);
+ dlclose(module);
+ exit(1);
+ }
+
+ /* call fmt_info() through a pointer*/
+ printf("%s\n", fmt());
+
+ /* close module */
+ if(dlclose(module))
+ {
+ perror("error");
+ exit(1);
+ }
+
+ return 0;
+ }
+
+ # gcc -o test main.c -ldl
+ # ./test
+ It is really cool format!
+ #
+
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>That's all! :) Our test program has just loaded <u>module.so</u> and called <u>fmt_info()</u>, located in it. It is very simple, isn't ?
+<br><br>
+</ul>
+
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-olibs2.html b/doc/html/ksquirrel-libs-olibs2.html
new file mode 100644
index 0000000..710df8a
--- /dev/null
+++ b/doc/html/ksquirrel-libs-olibs2.html
@@ -0,0 +1,1620 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+<DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="title"
+><A
+NAME="AEN2"
+></A
+>C++ dlopen mini HOWTO</H1
+><H3
+CLASS="author"
+><A
+NAME="AEN4"
+>Aaron Isotton</A
+></H3
+><DIV
+CLASS="affiliation"
+><DIV
+CLASS="address"
+><P
+CLASS="address"
+><TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:aaron@isotton.com"
+>aaron@isotton.com</A
+>&#62;</TT
+></P
+></DIV
+></DIV
+><P
+CLASS="pubdate"
+>2003-08-12<BR></P
+><DIV
+CLASS="revhistory"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+><TR
+><TH
+ALIGN="LEFT"
+VALIGN="TOP"
+COLSPAN="3"
+><B
+>Revision History</B
+></TH
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.03</TD
+><TD
+ALIGN="LEFT"
+>2003-08-12</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Added reference to the GLib Dynamic Module
+ Loader. Thanks to G. V. Sriraam for the pointer.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.02</TD
+><TD
+ALIGN="LEFT"
+>2002-12-08</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Added FAQ. Minor changes</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.01</TD
+><TD
+ALIGN="LEFT"
+>2002-06-30</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Updated virtual destructor explanation. Minor changes.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.00</TD
+><TD
+ALIGN="LEFT"
+>2002-06-19</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Moved copyright and license section to the
+ beginning. Added terms section. Minor changes.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 0.97</TD
+><TD
+ALIGN="LEFT"
+>2002-06-19</TD
+><TD
+ALIGN="LEFT"
+>Revised by: JYG</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Entered minor grammar and sentence level changes.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 0.96</TD
+><TD
+ALIGN="LEFT"
+>2002-06-12</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Added bibliography. Corrected explanation of extern
+ functions and variables.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 0.95</TD
+><TD
+ALIGN="LEFT"
+>2002-06-11</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Minor improvements.</TD
+></TR
+></TABLE
+></DIV
+><DIV
+><DIV
+CLASS="abstract"
+><A
+NAME="AEN47"
+></A
+><P
+></P
+><P
+>How to dynamically load C++ functions and classes using
+ the <TT
+CLASS="function"
+>dlopen</TT
+> API.</P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="#intro"
+>Introduction</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="#copyright"
+>Copyright and License</A
+></DT
+><DT
+>1.2. <A
+HREF="#disclaimer"
+>Disclaimer</A
+></DT
+><DT
+>1.3. <A
+HREF="#credits"
+>Credits / Contributors</A
+></DT
+><DT
+>1.4. <A
+HREF="#feedback"
+>Feedback</A
+></DT
+><DT
+>1.5. <A
+HREF="#AEN85"
+>Terms Used in this Document</A
+></DT
+></DL
+></DD
+><DT
+>2. <A
+HREF="#theproblem"
+>The Problem</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="#mangling"
+>Name Mangling</A
+></DT
+><DT
+>2.2. <A
+HREF="#AEN131"
+>Classes</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="#thesolution"
+>The Solution</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="#externC"
+><TT
+CLASS="literal"
+>extern "C"</TT
+></A
+></DT
+><DT
+>3.2. <A
+HREF="#loadingfunctions"
+>Loading Functions</A
+></DT
+><DT
+>3.3. <A
+HREF="#loadingclasses"
+>Loading Classes</A
+></DT
+></DL
+></DD
+><DT
+>4. <A
+HREF="#faq"
+>Frequently Asked Questions</A
+></DT
+><DT
+>5. <A
+HREF="#seealso"
+>See Also</A
+></DT
+><DT
+><A
+HREF="#AEN295"
+>Bibliography</A
+></DT
+></DL
+></DIV
+><DIV
+CLASS="section"
+><H1
+CLASS="section"
+><A
+NAME="intro"
+></A
+>1. Introduction</H1
+><P
+>&#13; A question which frequently arises among Unix C++ programmers is
+ how to load C++ functions and classes dynamically using the
+ <TT
+CLASS="function"
+>dlopen</TT
+> API.
+ </P
+><P
+>In fact, that is not always simple and needs some
+ explanation. That's what this mini HOWTO does.</P
+><P
+>An average understanding of the <SPAN
+CLASS="systemitem"
+>C</SPAN
+>
+ and <SPAN
+CLASS="systemitem"
+>C++</SPAN
+> programming language and of the
+ <TT
+CLASS="function"
+>dlopen</TT
+> API is necessary to understand this
+ document.</P
+><P
+>This HOWTO's master location is <A
+HREF="http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/"
+TARGET="_top"
+>http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/</A
+>.</P
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="copyright"
+></A
+>1.1. Copyright and License</H2
+><P
+>&#13; This document, <EM
+>C++ dlopen mini HOWTO</EM
+>, is
+ copyrighted (c) 2002 by <EM
+>Aaron Isotton</EM
+>.
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation
+ License, Version 1.1 or any later version published by the
+ Free Software Foundation; with no Invariant Sections, with no
+ Front-Cover Texts, and with no Back-Cover Texts.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="disclaimer"
+></A
+>1.2. Disclaimer</H2
+><P
+>&#13; No liability for the contents of this document can be
+ accepted. Use the concepts, examples and information at your
+ own risk. There may be errors and inaccuracies, that could be
+ damaging to your system. Proceed with caution, and although
+ this is highly unlikely, the author(s) do not take any
+ responsibility.
+ </P
+><P
+>&#13; All copyrights are held by their by their respective owners,
+ unless specifically noted otherwise. Use of a term in this
+ document should not be regarded as affecting the validity of
+ any trademark or service mark. Naming of particular products
+ or brands should not be seen as endorsements.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="credits"
+></A
+>1.3. Credits / Contributors</H2
+><P
+>&#13; In this document, I have the pleasure of acknowledging (in
+ alphabetic order):
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Joy Y Goodreau <TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:joyg (at) us.ibm.com"
+>joyg (at) us.ibm.com</A
+>&#62;</TT
+> for
+ her editing.</P
+></LI
+><LI
+><P
+>D. Stimitis <TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:stimitis (at) idcomm.com"
+>stimitis (at) idcomm.com</A
+>&#62;</TT
+>
+ for pointing out a few issues with the formatting and the
+ name mangling, as well as pointing out a few subtleties of
+ <TT
+CLASS="literal"
+>extern "C"</TT
+>.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="feedback"
+></A
+>1.4. Feedback</H2
+><P
+>&#13; Feedback is most certainly welcome for this document. Send
+ your additions, comments and criticisms to the following email
+ address: <TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:aaron@isotton.com"
+>aaron@isotton.com</A
+>&#62;</TT
+>.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="AEN85"
+></A
+>1.5. Terms Used in this Document</H2
+><P
+></P
+><DIV
+CLASS="variablelist"
+><DL
+><DT
+><TT
+CLASS="function"
+>dlopen</TT
+> API</DT
+><DD
+><P
+>The <TT
+CLASS="function"
+>dlclose</TT
+>,
+ <TT
+CLASS="function"
+>dlerror</TT
+>,
+ <TT
+CLASS="function"
+>dlopen</TT
+> and
+ <TT
+CLASS="function"
+>dlsym</TT
+> functions as described in the
+ <TT
+CLASS="literal"
+>dlopen(3)</TT
+> man page.</P
+><P
+>Notice that we use
+ <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="function"
+>dlopen</TT
+>"</SPAN
+> to refer to
+ the individual <TT
+CLASS="function"
+>dlopen</TT
+>
+ <EM
+>function</EM
+>, and
+ <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="function"
+>dlopen</TT
+> API"</SPAN
+> to refer
+ to the <EM
+>entire API</EM
+>.</P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="theproblem"
+></A
+>2. The Problem</H1
+><P
+>At some time you might have to load a library (and use its
+ functions) at runtime; this happens most often when you are
+ writing some kind of plug-in or module architecture for your
+ program.</P
+><P
+>In the C language, loading a library is very simple (calling
+ <TT
+CLASS="function"
+>dlopen</TT
+>, <TT
+CLASS="function"
+>dlsym</TT
+> and
+ <TT
+CLASS="function"
+>dlclose</TT
+> is enough), with C++ this is a bit
+ more complicated. The difficulties of loading a C++ library
+ dynamically are partially due to <A
+HREF="#mangling"
+>name
+ mangling</A
+>, and partially due to the fact that the
+ <TT
+CLASS="function"
+>dlopen</TT
+> API was written with C in mind, thus
+ not offering a suitable way to load classes.</P
+><P
+>Before explaining how to load libraries in C++, let's better
+ analyze the problem by looking at name mangling in more
+ detail. I recommend you read the explanation of name mangling,
+ even if you're not interested in it because it will help you
+ understanding why problems occur and how to solve them.</P
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="mangling"
+></A
+>2.1. Name Mangling</H2
+><P
+>In every C++ program (or library, or object file), all
+ non-static functions are represented in the binary file as
+ <EM
+>symbols</EM
+>. These symbols are special text
+ strings that uniquely identify a function in the program,
+ library, or object file.</P
+><P
+>In C, the symbol name is the same as the function name:
+ the symbol of <TT
+CLASS="function"
+>strcpy</TT
+> will be
+ <TT
+CLASS="computeroutput"
+>strcpy</TT
+>, and so on. This is
+ possible because in C no two non-static functions can have the
+ same name.</P
+><P
+>Because C++ allows overloading (different functions with
+ the same name but different arguments) and has many features C
+ does not &#8212; like classes, member functions, exception
+ specifications &#8212; it is not possible to simply use the
+ function name as the symbol name. To solve that, C++ uses
+ so-called <EM
+>name mangling</EM
+>, which transforms
+ the function name and all the necessary information (like the
+ number and size of the arguments) into some weird-looking
+ string which only the compiler knows about. The mangled name
+ of <TT
+CLASS="function"
+>foo</TT
+> might look like
+ <TT
+CLASS="computeroutput"
+>foo@4%6^</TT
+>, for example. Or it
+ might not even contain the word <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+>.</P
+><P
+> One of the problems with name mangling is that the C++
+ standard (currently [<SPAN
+CLASS="citation"
+>ISO14882</SPAN
+>]) does not
+ define how names have to be mangled; thus every compiler
+ mangles names in its own way. Some compilers even change their
+ name mangling algorithm between different versions (notably
+ g++ 2.x and 3.x). Even if you worked out how your particular
+ compiler mangles names (and would thus be able to load
+ functions via <TT
+CLASS="function"
+>dlsym</TT
+>), this would most
+ probably work with your compiler only, and might already be
+ broken with the next version.</P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="AEN131"
+></A
+>2.2. Classes</H2
+><P
+>Another problem with the <TT
+CLASS="function"
+>dlopen</TT
+> API
+ is the fact that it only supports loading
+ <EM
+>functions</EM
+>. But in C++ a library often
+ exposes a class which you would like to use in your
+ program. Obviously, to use that class you need to create an
+ instance of it, but that cannot be easily done.</P
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="thesolution"
+></A
+>3. The Solution</H1
+><DIV
+CLASS="section"
+><H2
+CLASS="section"
+><A
+NAME="externC"
+></A
+>3.1. <TT
+CLASS="literal"
+>extern "C"</TT
+></H2
+><P
+>C++ has a special keyword to declare a function with C
+ bindings: <TT
+CLASS="literal"
+>extern "C"</TT
+>. A function declared
+ as <TT
+CLASS="literal"
+>extern "C"</TT
+> uses the function name as
+ symbol name, just as a C function. For that reason, only
+ non-member functions can be declared as <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>, and they cannot be overloaded.</P
+><P
+>Although there are severe limitations, <TT
+CLASS="literal"
+>extern
+ "C"</TT
+> functions are very useful because they can be
+ dynamically loaded using <TT
+CLASS="function"
+>dlopen</TT
+> just like
+ a C function.</P
+><P
+>This does <EM
+>not</EM
+> mean that functions
+ qualified as <TT
+CLASS="literal"
+>extern "C"</TT
+> cannot contain C++
+ code. Such a function is a full-featured C++ function which
+ can use C++ features and take any type of argument.</P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="loadingfunctions"
+></A
+>3.2. Loading Functions</H2
+><P
+>In C++ functions are loaded just like in C, with
+ <TT
+CLASS="function"
+>dlsym</TT
+>. The functions you want to load
+ must be qualified as <TT
+CLASS="literal"
+>extern "C"</TT
+> to avoid
+ the symbol name being mangled.</P
+><DIV
+CLASS="example"
+><A
+NAME="AEN156"
+></A
+><P
+><B
+>Example 1. Loading a Function</B
+></P
+><P
+>main.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include &#60;iostream&#62;
+#include &#60;dlfcn.h&#62;
+
+
+int main() {
+ using std::cout;
+ using std::cerr;
+
+ cout &#60;&#60; "C++ dlopen demo\n\n";
+
+ // open the library
+ cout &#60;&#60; "Opening hello.so...\n";
+ void* handle = dlopen("./hello.so", RTLD_LAZY);
+
+ if (!handle) {
+ cerr &#60;&#60; "Cannot open library: " &#60;&#60; dlerror() &#60;&#60; '\n';
+ return 1;
+ }
+
+ // load the symbol
+ cout &#60;&#60; "Loading symbol hello...\n";
+ typedef void (*hello_t)();
+ hello_t hello = (hello_t) dlsym(handle, "hello");
+ if (!hello) {
+ cerr &#60;&#60; "Cannot load symbol 'hello': " &#60;&#60; dlerror() &#60;&#60;
+ '\n';
+ dlclose(handle);
+ return 1;
+ }
+
+ // use it to do the calculation
+ cout &#60;&#60; "Calling hello...\n";
+ hello();
+
+ // close the library
+ cout &#60;&#60; "Closing library...\n";
+ dlclose(handle);
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+>hello.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include &#60;iostream&#62;
+
+extern "C" void hello() {
+ std::cout &#60;&#60; "hello" &#60;&#60; '\n';
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>The function <TT
+CLASS="function"
+>hello</TT
+> is defined in
+ <TT
+CLASS="filename"
+>hello.cpp</TT
+>as <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>; it is loaded in <TT
+CLASS="filename"
+>main.cpp</TT
+>
+ with the <TT
+CLASS="function"
+>dlsym</TT
+> call. The function must be
+ qualified as <TT
+CLASS="literal"
+>extern "C"</TT
+> because otherwise
+ we wouldn't know its symbol name.</P
+><DIV
+CLASS="warning"
+><P
+></P
+><TABLE
+CLASS="warning"
+WIDTH="100%"
+BORDER="0"
+><TR
+><TD
+WIDTH="25"
+ALIGN="CENTER"
+VALIGN="TOP"
+><IMG
+SRC="../images/warning.gif"
+HSPACE="5"
+ALT="Warning"></TD
+><TD
+ALIGN="LEFT"
+VALIGN="TOP"
+><P
+>There are two different forms of the
+ <TT
+CLASS="literal"
+>extern "C"</TT
+> declaration: <TT
+CLASS="literal"
+>extern
+ "C"</TT
+> as used above, and <TT
+CLASS="literal"
+>extern "C" {
+ &#8230; }</TT
+> with the declarations between the
+ braces. The first (inline) form is a declaration with extern
+ linkage and with C language linkage; the second only affects
+ language linkage. The following two declarations are thus
+ equivalent:
+
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN174"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" int foo;
+extern "C" void bar();
+ </PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+ and
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN176"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" {
+ extern int foo;
+ extern void bar();
+ }</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+
+ As there is no difference between an
+ <TT
+CLASS="literal"
+>extern</TT
+> and a
+ non-<TT
+CLASS="literal"
+>extern</TT
+> <EM
+>function</EM
+>
+ declaration, this is no problem as long as you are not
+ declaring any variables. If you declare
+ <EM
+>variables</EM
+>, keep in mind that
+
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN182"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" int foo;</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+ and
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN184"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" {
+ int foo;
+}</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+
+ are <EM
+>not</EM
+> the same thing.</P
+><P
+>For further clarifications, refer to
+ [<SPAN
+CLASS="citation"
+>ISO14882</SPAN
+>], 7.5, with special attention
+ to paragraph 7, or to [<SPAN
+CLASS="citation"
+>STR2000</SPAN
+>],
+ paragraph 9.2.4.</P
+><P
+>Before doing fancy things with extern variables, peruse
+ the documents listed in the <A
+HREF="#seealso"
+>see
+ also</A
+> section.</P
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="loadingclasses"
+></A
+>3.3. Loading Classes</H2
+><P
+>Loading classes is a bit more difficult because we need
+ an <EM
+>instance</EM
+> of a class, not just a
+ pointer to a function.</P
+><P
+>We cannot create the instance of the class using
+ <TT
+CLASS="literal"
+>new</TT
+> because the class is not defined in the
+ executable, and because (under some circumstances) we don't
+ even know its name.</P
+><P
+>The solution is achieved through polymorphism. We define a
+ base, <EM
+>interface</EM
+> class with virtual
+ members <EM
+>in the executable</EM
+>, and a derived,
+ <EM
+>implementation</EM
+> class <EM
+>in the
+ module</EM
+>. Generally the interface class is
+ abstract (a class is abstract if it has pure virtual
+ functions).</P
+><P
+>As dynamic loading of classes is generally used for
+ plug-ins &#8212; which must expose a clearly defined interface
+ &#8212; we would have had to define an interface and derived
+ implementation classes anyway.</P
+><P
+>Next, while still in the module, we define two additional helper
+ functions, known as <EM
+>class factory
+ functions</EM
+>. One of these functions creates an instance of the
+ class and returns a pointer to it. The other function takes a
+ pointer to a class created by the factory and destroys
+ it. These two functions are qualified as <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>.</P
+><P
+>To use the class from the module, load the two factory
+ functions using <TT
+CLASS="function"
+>dlsym</TT
+> just <A
+HREF="#loadingfunctions"
+>as we loaded the the hello
+ function</A
+>; then, we can create and destroy as many
+ instances as we wish.</P
+><DIV
+CLASS="example"
+><A
+NAME="AEN210"
+></A
+><P
+><B
+>Example 2. Loading a Class</B
+></P
+><P
+>Here we use a generic <TT
+CLASS="classname"
+>polygon</TT
+>
+ class as interface and the derived class
+ <TT
+CLASS="classname"
+>triangle</TT
+> as implementation.</P
+><P
+>main.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include "polygon.hpp"
+#include &#60;iostream&#62;
+#include &#60;dlfcn.h&#62;
+
+int main() {
+ using std::cout;
+ using std::cerr;
+
+ // load the triangle library
+ void* triangle = dlopen("./triangle.so", RTLD_LAZY);
+ if (!triangle) {
+ cerr &#60;&#60; "Cannot load library: " &#60;&#60; dlerror() &#60;&#60; '\n';
+ return 1;
+ }
+
+ // load the symbols
+ create_t* create_triangle = (create_t*) dlsym(triangle, "create");
+ destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
+ if (!create_triangle || !destroy_triangle) {
+ cerr &#60;&#60; "Cannot load symbols: " &#60;&#60; dlerror() &#60;&#60; '\n';
+ return 1;
+ }
+
+ // create an instance of the class
+ polygon* poly = create_triangle();
+
+ // use the class
+ poly-&#62;set_side_length(7);
+ cout &#60;&#60; "The area is: " &#60;&#60; poly-&#62;area() &#60;&#60; '\n';
+
+ // destroy the class
+ destroy_triangle(poly);
+
+ // unload the triangle library
+ dlclose(triangle);
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+>polygon.hpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#ifndef POLYGON_HPP
+#define POLYGON_HPP
+
+class polygon {
+protected:
+ double side_length_;
+
+public:
+ polygon()
+ : side_length_(0) {}
+
+ void set_side_length(double side_length) {
+ side_length_ = side_length;
+ }
+
+ virtual double area() const = 0;
+};
+
+// the types of the class factories
+typedef polygon* create_t();
+typedef void destroy_t(polygon*);
+
+#endif
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+>triangle.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include "polygon.hpp"
+#include &#60;cmath&#62;
+
+class triangle : public polygon {
+public:
+ virtual double area() const {
+ return side_length_ * side_length_ * sqrt(3) / 2;
+ }
+};
+
+
+// the class factories
+
+extern "C" polygon* create() {
+ return new triangle;
+}
+
+extern "C" void destroy(polygon* p) {
+ delete p;
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>There are a few things to note when loading classes:</P
+><P
+></P
+><UL
+><LI
+><P
+>You must provide <EM
+>both</EM
+> a creation
+ and a destruction function; you must
+ <EM
+>not</EM
+> destroy the instances using
+ <TT
+CLASS="literal"
+>delete</TT
+> from inside the executable, but
+ always pass it back to the module. This is due to the fact
+ that in C++ the operators <TT
+CLASS="literal"
+>new</TT
+> and
+ <TT
+CLASS="literal"
+>delete</TT
+> may be overloaded; this would
+ cause a non-matching <TT
+CLASS="literal"
+>new</TT
+> and
+ <TT
+CLASS="literal"
+>delete</TT
+> to be called, which could cause
+ anything from nothing to memory leaks and segmentation
+ faults. The same is true if different standard libraries
+ are used to link the module and the executable.</P
+></LI
+><LI
+><P
+>The destructor of the interface class should be
+ virtual in any case. There <EM
+>might</EM
+> be
+ very rare cases where that would not be necessary, but it
+ is not worth the risk, because the additional overhead can
+ generally be ignored.</P
+><P
+>If your base class needs no destructor, define an
+ empty (and <TT
+CLASS="literal"
+>virtual</TT
+>) one anyway;
+ otherwise you <EM
+>will have problems</EM
+>
+ sooner or later; I can guarantee you that. You can read
+ more about this problem in the comp.lang.c++ FAQ at <A
+HREF="http://www.parashift.com/c++-faq-lite/"
+TARGET="_top"
+>http://www.parashift.com/c++-faq-lite/</A
+>, in
+ section 20.</P
+></LI
+></UL
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="faq"
+></A
+>4. Frequently Asked Questions</H1
+><DIV
+CLASS="qandaset"
+><DL
+><DT
+>4.1. <A
+HREF="#AEN243"
+>I'm using Windows and I can't find the
+ <TT
+CLASS="filename"
+>dlfcn.h</TT
+> header file on my PC! What's
+ the problem?</A
+></DT
+><DT
+>4.2. <A
+HREF="#AEN257"
+>Is there some kind of <TT
+CLASS="function"
+>dlopen</TT
+>-compatible
+ wrapper for the Windows <TT
+CLASS="function"
+>LoadLibrary</TT
+>
+ API?</A
+></DT
+></DL
+><DIV
+CLASS="qandaentry"
+><DIV
+CLASS="question"
+><P
+><A
+NAME="AEN243"
+></A
+><B
+>4.1. </B
+>I'm using Windows and I can't find the
+ <TT
+CLASS="filename"
+>dlfcn.h</TT
+> header file on my PC! What's
+ the problem?</P
+></DIV
+><DIV
+CLASS="answer"
+><P
+><B
+> </B
+>The problem is, as usual, Windows. There is no
+ <TT
+CLASS="filename"
+>dlfcn.h</TT
+> header on Windows,and there is
+ no <TT
+CLASS="function"
+>dlopen</TT
+> API. There is a similar API
+ around the <TT
+CLASS="function"
+>LoadLibrary</TT
+> function, and
+ most of what is written here applies to it, too.
+ Alternatively, you can use libltdl (included in libtool) to
+ <SPAN
+CLASS="QUOTE"
+>"emulate"</SPAN
+> <TT
+CLASS="function"
+>dlopen</TT
+> on a
+ variety of platforms.</P
+><P
+>You should also read section 4, <SPAN
+CLASS="QUOTE"
+>"Dynamically
+ Loaded (DL) Libraries"</SPAN
+>, of the <A
+HREF="http://www.dwheeler.com/program-library"
+TARGET="_top"
+>Program Library
+ HOWTO</A
+> for more techniques to load libraries and
+ create classes independently of your platform.</P
+></DIV
+></DIV
+><DIV
+CLASS="qandaentry"
+><DIV
+CLASS="question"
+><P
+><A
+NAME="AEN257"
+></A
+><B
+>4.2. </B
+>Is there some kind of <TT
+CLASS="function"
+>dlopen</TT
+>-compatible
+ wrapper for the Windows <TT
+CLASS="function"
+>LoadLibrary</TT
+>
+ API?</P
+></DIV
+><DIV
+CLASS="answer"
+><P
+><B
+> </B
+>I don't know of any, and I don't think there'll ever be one
+ supporting all of <TT
+CLASS="function"
+>dlopen</TT
+>'s options.</P
+><P
+>There are alternatives though: libtltdl (a part of libtool),
+ which wraps a variety of different dynamic loading APIs, among
+ others <TT
+CLASS="function"
+>dlopen</TT
+> and
+ <TT
+CLASS="function"
+>LoadLibrary</TT
+>. Another one is the <A
+HREF="http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-of-modules.html"
+TARGET="_top"
+>Dynamic
+ Module Loading functionality of GLib</A
+>. You can use one
+ of these to ensure better possible cross-platform compatibility.
+ I've never used any of them, so I can't tell you how stable they
+ are and whether they really work.</P
+></DIV
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="seealso"
+></A
+>5. See Also</H1
+><P
+></P
+><UL
+><LI
+><P
+>The <TT
+CLASS="function"
+>dlopen(3)</TT
+> man page. It explains
+ the purpose and the use of the <TT
+CLASS="function"
+>dlopen</TT
+>
+ API.</P
+></LI
+><LI
+><P
+>The article <A
+HREF="http://www.linuxjournal.com/article.php?sid=3687"
+TARGET="_top"
+>&#13; <I
+CLASS="citetitle"
+>Dynamic Class Loading for C++ on
+ Linux</I
+></A
+> by James Norton published on the
+ <A
+HREF="http://www.linuxjournal.com/"
+TARGET="_top"
+>Linux
+ Journal</A
+>.</P
+></LI
+><LI
+><P
+>Your favorite C++ reference about <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>, inheritance, virtual functions,
+ <TT
+CLASS="literal"
+>new</TT
+> and <TT
+CLASS="literal"
+>delete</TT
+>. I
+ recommend [<SPAN
+CLASS="citation"
+>STR2000</SPAN
+>].</P
+></LI
+><LI
+><P
+>[<SPAN
+CLASS="citation"
+>ISO14882</SPAN
+>]</P
+></LI
+><LI
+><P
+>The <A
+HREF="http://www.dwheeler.com/program-library"
+TARGET="_top"
+>Program Library
+ HOWTO</A
+>, which tells you most things you'll ever need
+ about static, shared and dynamically loaded libraries and how
+ to create them. Highly recommended.</P
+></LI
+><LI
+><P
+>The <A
+HREF="http://tldp.org/HOWTO/GCC-HOWTO/index.html"
+TARGET="_top"
+>Linux GCC
+ HOWTO</A
+> to learn more about how to create libraries
+ with GCC.</P
+></LI
+></UL
+></DIV
+><A
+NAME="AEN295"
+></A
+><HR><H1
+><A
+NAME="AEN295"
+></A
+>Bibliography</H1
+><DIV
+CLASS="bibliomixed"
+><A
+NAME="AEN296"
+></A
+><P
+CLASS="bibliomixed"
+>&#13; ISO14482 <I
+>ISO/IEC 14482-1998 &#8212; The
+ C++ Programming Language</I
+>. Available as
+ PDF and as printed book from <A
+HREF="http://webstore.ansi.org/"
+TARGET="_top"
+>http://webstore.ansi.org/</A
+>.
+ </P
+></DIV
+><DIV
+CLASS="bibliomixed"
+><A
+NAME="AEN301"
+></A
+><P
+CLASS="bibliomixed"
+>&#13; STR2000
+ <SPAN
+CLASS="AUTHOR"
+>Bjarne Stroustrup</SPAN
+>
+ <I
+>The C++ Programming Language</I
+>, Special
+ Edition.
+ ISBN 0-201-70073-5.
+ Addison-Wesley.
+ </P
+></DIV
+></DIV
+>
+
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-olibs3.html b/doc/html/ksquirrel-libs-olibs3.html
new file mode 100644
index 0000000..46150ec
--- /dev/null
+++ b/doc/html/ksquirrel-libs-olibs3.html
@@ -0,0 +1,365 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+<center><h3><b>How to write a new library for KSquirrel (for example, it will decode abstract 'ttx' format) ?</b></h3></center>
+
+<ul>
+<li>Create a directory with necessary sources ('generate' is distributed with ksquirrel-libs):
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+# ./generate ttx -build
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>Typical fmt_codec_ttx_defs.h
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+#ifndef KSQUIRREL_READ_IMAGE_ttx
+#define KSQUIRREL_READ_IMAGE_ttx
+
+// Define constants you need here
+
+#endif
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>Typical fmt_codec_ttx.h
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_ttx_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_ttx_H
+
+#include "fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ fmt_codec();
+ ~fmt_codec();
+
+ virtual std::string fmt_version();
+ virtual std::string fmt_quickinfo();
+ virtual std::string fmt_filter();
+ virtual std::string fmt_mime();
+ virtual std::string fmt_pixmap();
+ virtual std::string fmt_extension(const s32 bpp);
+
+ virtual bool fmt_readable() const;
+ virtual s32 fmt_read_init(const std::string &amp;file);
+ virtual s32 fmt_read_next();
+ virtual s32 fmt_read_next_pass();
+ virtual s32 fmt_read_scanline(RGBA *scan);
+ virtual void fmt_read_close();
+
+
+ virtual bool fmt_writable() const;
+ virtual void fmt_getwriteoptions(fmt_writeoptionsabs *);
+ virtual s32 fmt_write_init(const std::string &amp;file, const fmt_image &amp;image,
+ const fmt_writeoptions &amp;opt);
+ virtual s32 fmt_write_next();
+ virtual s32 fmt_write_next_pass();
+ virtual s32 fmt_write_scanline(RGBA *scan);
+ virtual void fmt_write_close();
+
+ private:
+ // define variables you need here
+};
+
+extern "C" fmt_codec_base* fmt_codec_create()
+{
+ return (new fmt_codec);
+}
+
+extern "C" void fmt_codec_destroy(fmt_codec_base *p)
+{
+ delete p;
+}
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>Typical fmt_codec_ttx.cpp
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+
+ <pre>
+
+#include &#60;iostream&#62;
+
+#include "fmt_types.h"
+#include "fileio.h"
+#include "fmt_codec_ttx_defs.h"
+#include "fmt_codec_ttx.h"
+
+#include "error.h"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+<b>Returns library's version</b>
+std::string fmt_codec::fmt_version()
+{
+ return std::string("0.0.1");
+}
+
+<b>Returns common information on ttx format</b>
+std::string fmt_codec::fmt_quickinfo()
+{
+ return std::string("TTX is a very cool format!");
+}
+
+<b>Filter for a file manager (with a blank after
+each extension)</b>
+std::string fmt_codec::fmt_filter()
+{
+ return std::string("*.ttx1 *.ttx2 *.ttx3 ");
+}
+
+<b>The regular expression defining the file type
+(usually first 2-5 characters in a file).
+This example shows, that format TTX is defined by header
+TTX7, TTX8 or TTX9. If the file has no header
+ (like .ico and .pix) this function should return empty string.</b>
+std::string fmt_codec::fmt_mime()
+{
+ return std::string("TTX[789]");
+}
+
+<b>Compile <a href='bits.html'>this program</a>,
+create PNG icon 16x16 and run
+#./bits icon.png > icon.bits.
+Then copy contents of icon.bits here</b>
+std::string fmt_codec::fmt_pixmap()
+{
+ return std::string("");
+}
+
+<b>Open file, initialize variables, etc.</b>
+s32 fmt_codec::fmt_read_init(const std::string &amp;file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQERR_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQERR_OK;
+}
+
+<b>This method will be called BEFORE decoding of each image in a file,
+so we should seek to correct file offset or do something important now.
+Return SQERR_NOTOK, if the next image can't be decoded (no such image),
+and any other error code on error.</b>
+s32 fmt_codec::fmt_read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQERR_NOTOK; <b>return, if TTX can
+ have only one image.</b>
+
+ fmt_image image;
+
+ <b>Non-interlaced image has 1 pass.
+ If you need to define another value, do it here</b>
+ image.passes = 1;
+
+<b>Here you should read necessary data from file,
+and initialize finfo.image[currentImage].w,h,bpp. Return error
+code you need on error.</b>
+<b>...</b>
+
+ image.compression = "-";
+ image.colorspace = "RGB";
+
+ finfo.image.push_back(image);
+
+ return SQERR_OK;
+}
+
+<b>This method will be called BEFORE decoding of each pass
+in the interlaced image.</b>
+s32 fmt_codec::fmt_read_next_pass()
+{
+ <b>Our TTX fromat can't be interlaced, so we
+ won't do anything, just return SQERR_OK</b>
+ return SQERR_OK;
+}
+
+<b>Reads scanline in 'scan'. This example just fills
+'scan' with white color (RGBA(255,255,255,255))</b>
+s32 fmt_codec::fmt_read_scanline(RGBA *scan)
+{
+ memset(scan, 255, finfo.image[currentImage].w * sizeof(RGBA));
+
+ return SQERR_OK;
+}
+
+<b>Closes everything, frees allocated memory, etc.</b>
+void fmt_codec::fmt_read_close()
+{
+ frs.close();
+
+ // you should free information on close
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+<b>Returns write options for TTX format. This method won't be
+called, if fmt_writable() returns 'false'</b>
+void fmt_codec::fmt_getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ <b>Can TTX format be interlaced ? No.</b>
+ opt->interlaced = false;
+
+ <b>With which compression it can be compressed ?
+ With no compression (like not-RLE BMP).</b>
+ opt->compression_scheme = CompressionNo;
+
+ <b>minimum, maximum, and default compression level.
+ Ignored, if the compression is CompressionNo.</b>
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+
+ <b>TTX can't be interlaced, passes = 1</b>
+ opt->passes = 1;
+
+ <b>KSquirrel shouldn't flip the image
+ before writing</b>
+ opt->needflip = false;
+}
+
+<b>Same to fmt_read_init()</b>
+s32 fmt_codec::fmt_write_init(const std::string &amp;file, const fmt_image &image,
+ const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+<b>Same to fmt_read_next()</b>
+s32 fmt_codec::fmt_write_next()
+{
+ return SQE_OK;
+}
+
+<b>Same to fmt_read_next_pass()</b>
+s32 fmt_codec::fmt_write_next_pass()
+{
+ return SQE_OK;
+}
+
+<b>Write scanline. Same to fmt_read_scanline()</b>
+s32 fmt_codec::fmt_write_scanline(RGBA *scan)
+{
+ ...
+ return SQE_OK;
+}
+
+<b>Same to fmt_read_init()</b>
+void fmt_codec::fmt_write_close()
+{
+ fws.close();
+}
+
+<b>Can this library write TTX ? No.</b>
+bool fmt_codec::fmt_writable() const
+{
+ return false;
+}
+
+<b>Can this library read TTX ? Yes.</b>
+bool fmt_codec::fmt_readable() const
+{
+ return true;
+}
+
+<b>Some libraries support several image types (like PNM library).
+This method should be used by writing function to determine file extension by image's bpp.
+For example, 1 bpp means .pbm, 8 bpp - pgm</b>"
+std::string fmt_codec::fmt_extension(const s32 /*bpp*/)
+{
+ return std::string("");
+}
+
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br><br>
+<li>Compile it
+<br><br>
+<table cellpadding="2" cellspacing="2" width="70%" align="center">
+ <tbody>
+ <tr>
+ <td valign="top" bgcolor="#CCCCCC">
+ <pre>
+# ./compile-c++
+#
+ </pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<br><br>
+<li>That's all. You've just created a new decoder for KSquirrel. Copy libSQ_codec_ttx.so in /usr/lib/ksquirrel-libs.
+</ul>
+
+</body>
+</html>
diff --git a/doc/html/ksquirrel-libs-struct.html b/doc/html/ksquirrel-libs-struct.html
new file mode 100644
index 0000000..154d1d5
--- /dev/null
+++ b/doc/html/ksquirrel-libs-struct.html
@@ -0,0 +1,201 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+In ksquirrel-libs I use the following wrappers for built-in types (valid for x86, 32-bit platform): int - <b>s32</b>,
+unsigned int - <b>u32</b>, short - <b>s16</b>, unsigned short - <b>u16</b>, char - <b>s8</b>, unsinged char - <b>u8</b>.
+All of them are defined in <b>fmt_types.h</b>.
+
+<pre>
+<b>Defines one metainfo record. For example:
+ {"JPEG 'COM' marker", "File written by Photoshop"}</b>
+struct fmt_metaentry
+{
+ <b>Group name, for example "SGI Image name"</b>
+ std::string group;
+
+ <b>Information. For example "This image was created with MegaTool 0.5.1"</b>
+ std::string data;
+
+};
+
+<b>Defines 32-bit pixel. Red, Green, Blue and Alpha channel.</b>
+struct RGBA
+{
+ RGBA() : r(0), g(0), b(0), a(0)
+ {}
+
+ RGBA(s32 r1, s32 g1, s32 b1, s32 a1) : r(r1), g(g1), b(b1), a(a1)
+ {}
+
+ u8 r;
+ u8 g;
+ u8 b;
+ u8 a;
+}PACKED;
+
+<b>Defines 24-bit color pixel. Red, Green, Blue.</b>
+struct RGB
+{
+ RGB() : r(0), g(0), b(0)
+ {}
+
+ RGB(s32 r1, s32 g1, s32 b1) : r(r1), g(g1), b(b1)
+ {}
+
+ u8 r;
+ u8 g;
+ u8 b;
+
+}PACKED;
+
+<b>Defines one image. It stores the main information about one image: width,
+height, metainfo, ...</b>
+struct fmt_image
+{
+ fmt_image() : w(0), h(0), bpp(0), hasalpha(false), needflip(false),
+ delay(0), interlaced(false), passes(1)
+ {}
+
+ <b>width of the image</b>
+ s32 w;
+ <b>height</b>
+ s32 h;
+ <b>bits per pixel</b>
+ s32 bpp;
+ <b>has alpha channel ?</b>
+ bool hasalpha;
+ <b>flip ? (for example BMP needs)</b>
+ bool needflip;
+ <b>only for animated images (like GIF)</b>
+ s32 delay;
+ <b>Is it interlaced or normal ?</b>
+ bool interlaced;
+ <b>Item 'passes' stores a number of passes if the image is iterlaced, or 1 otherwise.</b>
+ s32 passes;
+ <b>color space (RGB, RGBA, CMYK, LAB ...)</b>
+ std::string colorspace;
+ <b>compression type (RLE, JPEG, Deflate ...)</b>
+ std::string compression;
+
+};
+
+<b>The main structure in ksquirrel-libs. It contains all information needed
+to decode a file with one or more images.</b>
+struct fmt_info
+{
+ fmt_info() : animated(false)
+ {}
+
+ <b>Array of fmt_image structures. One structure defines one image.</b>
+ std::vector&#60;fmt_image&#62; image;
+
+ <b>Metainfo entries</b>
+ std::vector&#60;fmt_metaentry&#62; meta;
+
+ <b>Is it animated or static ?</b>
+ bool animated;
+
+};
+
+
+enum fmt_compression {
+
+<b>No compression</b>
+CompressionNo = 1,
+
+<b>RLE compression</b>
+CompressionRLE = 2,
+
+<b>Internal cmpression. E.g. compression_level will be passed to internal routines,
+for example in libjpeg, libpng.
+Note: if the image can be compressed with RLE encoding and with only RLE
+encoding, compression_scheme should be CompressionInternal</b>
+CompressionInternal = 4 };
+
+<b>Write options for image format</b>
+struct fmt_writeoptionsabs
+{
+ <b>Can be interlaced ?</b>
+ bool interlaced;
+
+ <b>if interlaced, this value should store preferred number of passes.</b>
+ s32 passes;
+
+ <b>if the image should be flipped before writing</b>
+ bool needflip;
+
+ <b> with which compression it can be encoded ?
+ for example: CompressionNo | CompressionRLE.
+ it means, that image can be encoded with RLE
+ method or can be saved without any compression.</b>
+ s32 compression_scheme;
+
+ <b> minimum compression level, maximum and default.
+ For example, JPEG library has minimum = 0,
+ maximum = 100 and default = 25.</b>
+ s32 compression_min, compression_max, compression_def;
+
+}PACKED;
+
+<b>this information will be passed to writing function</b>
+struct fmt_writeoptions
+{
+ <b>write interlaced image or normal ?</b>
+ bool interlaced;
+
+ <b>with which compression encode the image ?</b>
+ fmt_compression compression_scheme;
+
+ <b>compression level</b>
+ s32 compression_level;
+
+ <b>has alpha channel ? If no, A channel in RGBA image will be ignored</b>
+ bool alpha;
+
+}PACKED;
+
+
+<b>We can use comparison operators for RGBA and RGB pixels. For example:</b>
+<strong>
+#define SQ_NEED_OPERATOR_RGBA_RGB
+
+RGBA rgba;
+RGB rgb;
+...
+if(rgba == rgb)
+ printf("Pixels are equal!\n");
+</strong>
+#if defined SQ_NEED_OPERATOR_RGBA_RGBA
+static s32 operator== (const RGBA &rgba1, const RGBA &rgba2)
+{
+ return (rgba1.r == rgba2.r && rgba1.g == rgba2.g && rgba1.b == rgba2.b && rgba1.a == rgba2.a);
+}
+#endif
+
+#if defined SQ_NEED_OPERATOR_RGB_RGBA
+static s32 operator== (const RGB &rgb, const RGBA &rgba)
+{
+ return (rgb.r == rgba.r && rgb.g == rgba.g && rgb.b == rgba.b);
+}
+#endif
+
+#if defined SQ_NEED_OPERATOR_RGBA_RGB
+static s32 operator== (const RGBA &rgba, const RGB &rgb)
+{
+ return (rgba.r == rgb.r && rgba.g == rgb.g && rgba.b == rgb.b);
+}
+#endif
+
+#endif
+</pre>
+</body>
+</html>
diff --git a/doc/html/styles.css b/doc/html/styles.css
new file mode 100644
index 0000000..62e1aa3
--- /dev/null
+++ b/doc/html/styles.css
@@ -0,0 +1,26 @@
+h1, h2, h3 { font-family: tahoma, verdana, Helvetica, arial, sans-serif; }
+
+a:link.menulink { color: #ffffff; text-decoration: none }
+a:visited.menulink { color: #ffffff; text-decoration: none }
+a:active.menulink { color: #ffffff; text-decoration: none }
+a:hover.menulink { color: #ffffff; text-decoration: underline }
+
+body.index
+ {
+ background: #ffffff;
+ font-family: Tahoma, Arial, Helvetica, sans-serif; color: #000000;
+ }
+
+body {
+ background: #ffffff;
+ font-family: Tahoma, Arial, Helvetica, sans-serif; color: #000000;
+
+ background-repeat: no-repeat;
+ background-attachment: fixed;
+ background-image: url(belka_bkgr.gif);
+ background-position: right bottom;
+ }
+
+td.menuitem { padding: 3px; }
+
+p.red { text-indent: 8mm; }
diff --git a/doc/sources/Makefile.am b/doc/sources/Makefile.am
new file mode 100644
index 0000000..796800c
--- /dev/null
+++ b/doc/sources/Makefile.am
@@ -0,0 +1,24 @@
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources
+ $(mkinstalldirs) $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c
+ $(mkinstalldirs) $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c++
+ $(mkinstalldirs) $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx
+
+ $(INSTALL_DATA) c/module.c $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c/module.c
+ $(INSTALL_DATA) c/main.c $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c/main.c
+ $(INSTALL_SCRIPT) c/compile $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c/compile
+
+ $(INSTALL_SCRIPT) c++/compile $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c++/compile
+ $(INSTALL_DATA) c++/main.cpp $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c++/main.cpp
+ $(INSTALL_DATA) c++/triangle.cpp $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c++/triangle.cpp
+ $(INSTALL_DATA) c++/polygon.hpp $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c++/polygon.hpp
+ $(INSTALL_DATA) c++/README $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/c++/README
+
+ $(INSTALL_DATA) ttx/Makefile.am $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx/Makefile.am
+ $(INSTALL_DATA) ttx/README $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx/README
+ $(INSTALL_SCRIPT) ttx/compile-c++ $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx/compile-c++
+ $(INSTALL_DATA) ttx/fmt_codec_ttx_defs.h $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx/fmt_codec_ttx_defs.h
+ $(INSTALL_DATA) ttx/fmt_codec_ttx.h $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx/fmt_codec_ttx.h
+ $(INSTALL_DATA) ttx/fmt_codec_ttx.cpp $(DESTDIR)/usr/share/doc/ksquirrel-libs/$(PACKAGE_VERSION)/sources/ttx/fmt_codec_ttx.cpp
+
+EXTRA_DIST = c c++ ttx \ No newline at end of file
diff --git a/doc/sources/c++/README b/doc/sources/c++/README
new file mode 100644
index 0000000..189ebab
--- /dev/null
+++ b/doc/sources/c++/README
@@ -0,0 +1,3 @@
+Originally written by Aaron Isotton.
+Look for article "C++ dlopen mini HOWTO" in internet or
+visit http://ksquirrel.sf.net/ksquirrel-libs-olibs2.php \ No newline at end of file
diff --git a/doc/sources/c++/compile b/doc/sources/c++/compile
new file mode 100755
index 0000000..64687fa
--- /dev/null
+++ b/doc/sources/c++/compile
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+g++ -O2 -Wall -fPIC -c triangle.cpp
+g++ -shared -o triangle.so triangle.o
+g++ -o test main.cpp -ldl \ No newline at end of file
diff --git a/doc/sources/c++/main.cpp b/doc/sources/c++/main.cpp
new file mode 100644
index 0000000..b8fb8cd
--- /dev/null
+++ b/doc/sources/c++/main.cpp
@@ -0,0 +1,44 @@
+#include "polygon.hpp"
+
+#include <iostream>
+#include <dlfcn.h>
+
+int main()
+{
+ using std::cout;
+ using std::cerr;
+
+ // load the triangle library
+ void* triangle = dlopen("./triangle.so", RTLD_LAZY);
+
+ if (!triangle)
+ {
+ cerr << "Cannot load library: " << dlerror() << '\n';
+ return 1;
+ }
+
+ // load the symbols
+ create_t* create_triangle = (create_t*) dlsym(triangle, "create");
+ destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
+
+ if (!create_triangle || !destroy_triangle)
+ {
+ cerr << "Cannot load symbols: " << dlerror() << '\n';
+ return 1;
+ }
+
+ // create an instance of the class
+ polygon* poly = create_triangle();
+
+ // use the class
+ poly->set_side_length(7);
+ cout << "The area is: " << poly->area() << '\n';
+
+ // destroy the class
+ destroy_triangle(poly);
+
+ // unload the triangle library
+ dlclose(triangle);
+
+ return 0;
+}
diff --git a/doc/sources/c++/polygon.hpp b/doc/sources/c++/polygon.hpp
new file mode 100644
index 0000000..e3189bf
--- /dev/null
+++ b/doc/sources/c++/polygon.hpp
@@ -0,0 +1,25 @@
+#ifndef POLYGON_HPP
+#define POLYGON_HPP
+
+class polygon
+{
+ protected:
+ double side_length_;
+
+ public:
+ polygon() : side_length_(0)
+ {}
+
+ void set_side_length(double side_length)
+ {
+ side_length_ = side_length;
+ }
+
+ virtual double area() const = 0;
+};
+
+// the types of the class factories
+typedef polygon* create_t();
+typedef void destroy_t(polygon*);
+
+#endif
diff --git a/doc/sources/c++/triangle.cpp b/doc/sources/c++/triangle.cpp
new file mode 100644
index 0000000..96185d0
--- /dev/null
+++ b/doc/sources/c++/triangle.cpp
@@ -0,0 +1,22 @@
+#include "polygon.hpp"
+#include <cmath>
+
+class triangle : public polygon
+{
+ public:
+ virtual double area() const
+ {
+ return side_length_ * side_length_ * sqrt(3) / 2;
+ }
+};
+
+// the class factories
+extern "C" polygon* create()
+{
+ return new triangle;
+}
+
+extern "C" void destroy(polygon* p)
+{
+ delete p;
+}
diff --git a/doc/sources/c/compile b/doc/sources/c/compile
new file mode 100755
index 0000000..9be0fbb
--- /dev/null
+++ b/doc/sources/c/compile
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+gcc -Wall -O2 -fPIC -c module.c
+gcc -shared -o module.so module.o
+gcc -o test main.c -ldl \ No newline at end of file
diff --git a/doc/sources/c/main.c b/doc/sources/c/main.c
new file mode 100644
index 0000000..96d60ad
--- /dev/null
+++ b/doc/sources/c/main.c
@@ -0,0 +1,56 @@
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+#define PATH_LENGTH 256
+
+int main(int argc, char * argv[])
+{
+ char path[PATH_LENGTH], *msg = NULL;
+ const char* (*fmt)();
+ void *module;
+
+ getcwd(path, PATH_LENGTH);
+ strcat(path, "/");
+ strcat(path, "module.so");
+
+ /* Load module */
+ module = dlopen(path, RTLD_NOW);
+
+ /* Error ! */
+ if(!module)
+ {
+ msg = dlerror();
+
+ if(msg != NULL)
+ {
+ dlclose(module);
+ exit(1);
+ }
+ }
+
+ /* Try to resolve function "fmt_info()" */
+ fmt = dlsym(module, "fmt_info");
+
+ msg = dlerror();
+
+ if(msg != NULL)
+ {
+ perror(msg);
+ dlclose(module);
+ exit(1);
+ }
+
+ /* call fmt_info() through a pointer*/
+ printf("%s\n", fmt());
+
+ /* close module */
+ if(dlclose(module))
+ {
+ perror("error");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/doc/sources/c/module.c b/doc/sources/c/module.c
new file mode 100644
index 0000000..36c5d2a
--- /dev/null
+++ b/doc/sources/c/module.c
@@ -0,0 +1,4 @@
+const char* fmt_info()
+{
+ return "It is really cool format!";
+}
diff --git a/doc/sources/ttx/Makefile.am b/doc/sources/ttx/Makefile.am
new file mode 100644
index 0000000..4b3418e
--- /dev/null
+++ b/doc/sources/ttx/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I.. -I../include
+
+lib_LTLIBRARIES = libSQ_codec_ttx.la
+
+libSQ_codec_ttx_la_SOURCES = fmt_codec_ttx.cpp fmt_codec_ttx_defs.h
+
+libSQ_codec_ttx_la_LDFLAGS = -release 0.1.0
+
+libSQ_codec_ttx_la_LIBADD =
diff --git a/doc/sources/ttx/README b/doc/sources/ttx/README
new file mode 100644
index 0000000..ce1269e
--- /dev/null
+++ b/doc/sources/ttx/README
@@ -0,0 +1,3 @@
+this example should be compiled in ksquirrel-libs' tree.
+Put this directory in ksquirrel-libs/kernel, then cd to "ttx" and
+run ./compile-c++ \ No newline at end of file
diff --git a/doc/sources/ttx/compile-c++ b/doc/sources/ttx/compile-c++
new file mode 100755
index 0000000..86d3acb
--- /dev/null
+++ b/doc/sources/ttx/compile-c++
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+rm -f libkls_ttx.so
+
+g++ -I. -I../include -Wall -O2 -fPIC -c fmt_codec_ttx.cpp
+g++ -I. -I../include -Wall -O2 -fPIC -c ../kls_lib/fileio.cpp
+g++ -Wall -shared fileio.o fmt_codec_ttx.o -o libkls_ttx.so
+rm -f fmt_codec_ttx.o fileio.o \ No newline at end of file
diff --git a/doc/sources/ttx/fmt_codec_ttx.cpp b/doc/sources/ttx/fmt_codec_ttx.cpp
new file mode 100644
index 0000000..40c9f5d
--- /dev/null
+++ b/doc/sources/ttx/fmt_codec_ttx.cpp
@@ -0,0 +1,116 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_ttx_defs.h"
+#include "fmt_codec_ttx.h"
+
+#include "ksquirrel-libs/error.h"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "";
+ o->filter = "*. ";
+ o->mime = "";
+ o->pixmap = "";
+ o->config = "";
+ o->readable = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->canbemultiple = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+/*
+ image.w =
+ image.h =
+ image.bpp =
+*/
+
+ image.compression = "";
+ image.colorspace = "";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ RGBA rgba;
+ fmt_image *im = image(currentImage);
+
+ memset(scan, 255, im->w * sizeof(RGBA));
+
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/doc/sources/ttx/fmt_codec_ttx.h b/doc/sources/ttx/fmt_codec_ttx.h
new file mode 100644
index 0000000..fd44432
--- /dev/null
+++ b/doc/sources/ttx/fmt_codec_ttx.h
@@ -0,0 +1,37 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_ttx_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_ttx_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ // define variables you need here
+};
+
+#endif
diff --git a/doc/sources/ttx/fmt_codec_ttx_defs.h b/doc/sources/ttx/fmt_codec_ttx_defs.h
new file mode 100644
index 0000000..bd8bdcb
--- /dev/null
+++ b/doc/sources/ttx/fmt_codec_ttx_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_ttx
+#define KSQUIRREL_CODEC_DEFS_ttx
+
+// define constants here
+
+#endif
diff --git a/examples/qtapp/main.cpp b/examples/qtapp/main.cpp
new file mode 100644
index 0000000..91c4052
--- /dev/null
+++ b/examples/qtapp/main.cpp
@@ -0,0 +1,24 @@
+#include "myqt.h"
+
+#include <qapplication.h>
+#include <qvbox.h>
+#include <qpushbutton.h>
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+
+ QVBox *v = new QVBox;
+ QPushButton *b = new QPushButton("Show w3.bmp !", v);
+ MyQT *qt = new MyQT(v);
+
+ QVBox::connect(b, SIGNAL(clicked()), qt, SLOT(bind()));
+
+ v->setStretchFactor(qt, 1);
+
+ a.setMainWidget(v);
+ v->resize(512, 256);
+ v->show();
+
+ return a.exec();
+}
diff --git a/examples/qtapp/myqt.cpp b/examples/qtapp/myqt.cpp
new file mode 100644
index 0000000..9cd4b80
--- /dev/null
+++ b/examples/qtapp/myqt.cpp
@@ -0,0 +1,111 @@
+#include <qlibrary.h>
+#include <qapplication.h>
+#include <qfile.h>
+
+#include <qimage.h>
+
+#include "myqt.h"
+
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/error.h"
+
+MyQT::MyQT(QWidget *parent, const char *name) : QLabel(parent, name)
+{
+ setAlignment(Qt::AlignCenter);
+}
+
+MyQT::~MyQT()
+{}
+
+QPixmap MyQT::loadImage()
+{
+ QLibrary lib("/usr/lib/ksquirrel-libs/libkls_bmp.so");
+ lib.load();
+
+ if(!lib.isLoaded())
+ {
+ qWarning("Can't load BMP library.");
+ qApp->quit();
+ }
+
+ int i = 0;
+ fmt_info finfo;
+ RGBA *image;
+ int current = 0;
+
+ codec_create = (fmt_codec_base*(*)())lib.resolve("codec_create");
+ codec_destroy = (void (*)(fmt_codec_base*))lib.resolve("codec_destroy");
+
+ if(!codec_create || !codec_destroy)
+ {
+ qWarning("Library corrupted.");
+ lib.unload();
+ qApp->quit();
+ }
+
+ const char *s = "../w3.bmp";
+
+ if(!QFile::exists(s))
+ {
+ qWarning("Can't find example image.");
+ lib.unload();
+ qApp->quit();
+ }
+
+ codeK = codec_create();
+
+ i = codeK->read_init(s);
+
+ if(i != SQE_OK)
+ {
+ codeK->read_close();
+ return QPixmap();
+ }
+
+ i = codeK->read_next();
+
+ finfo = codeK->information();
+
+ if(i != SQE_OK)
+ {
+ codeK->read_close();
+ return QPixmap();
+ }
+
+ image = (RGBA*)calloc(finfo.image[current].w * finfo.image[current].h, sizeof(RGBA));
+
+ if(!image)
+ {
+ codeK->read_close();
+ return QPixmap();
+ }
+
+ memset(image, 255, finfo.image[current].w * finfo.image[current].h * sizeof(RGBA));
+
+ RGBA *scan;
+
+ for(int pass = 0;pass < finfo.image[current].passes;pass++)
+ {
+ codeK->read_next_pass();
+
+ for(int j = 0;j < finfo.image[current].h;j++)
+ {
+ scan = image + j * finfo.image[current].w;
+ codeK->read_scanline(scan);
+ }
+ }
+
+ if(finfo.image[current].needflip)
+ fmt_utils::flipv((char*)image, finfo.image[current].w * sizeof(RGBA), finfo.image[current].h);
+
+ codeK->read_close();
+
+ QImage im((unsigned char*)image, finfo.image[current].w, finfo.image[current].h, 32, 0, 0, QImage::LittleEndian);
+
+ return QPixmap(im.swapRGB());
+}
+
+void MyQT::bind()
+{
+ setPixmap(loadImage());
+}
diff --git a/examples/qtapp/myqt.h b/examples/qtapp/myqt.h
new file mode 100644
index 0000000..9e63d4f
--- /dev/null
+++ b/examples/qtapp/myqt.h
@@ -0,0 +1,33 @@
+#ifndef GLWIDGET_H
+#define GLWIDGET_H
+
+#include <qlabel.h>
+
+#include <csetjmp>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class MyQT : public QLabel
+{
+ Q_OBJECT
+
+ public:
+ MyQT(QWidget *parent = 0, const char *name = 0);
+ ~MyQT();
+
+ QPixmap loadImage();
+
+ public slots:
+ void bind();
+
+ private:
+ fmt_codec_base* (*codec_create)();
+ void (*codec_destroy)(fmt_codec_base*);
+
+ fmt_codec_base *codeK;
+
+};
+
+#endif
diff --git a/examples/qtapp/qtapp.pro b/examples/qtapp/qtapp.pro
new file mode 100644
index 0000000..9c658c0
--- /dev/null
+++ b/examples/qtapp/qtapp.pro
@@ -0,0 +1,11 @@
+######################################################################
+# Automatically generated by qmake (1.06c) Thu Mar 3 02:54:53 2005
+######################################################################
+
+TEMPLATE = app
+INCLUDEPATH += .
+INCLUDEPATH += ../../kernel/include
+
+# Input
+HEADERS += myqt.h
+SOURCES += main.cpp myqt.cpp ../../kernel/ksquirrel-libs/fmt_utils.cpp
diff --git a/examples/qtgl/main.cpp b/examples/qtgl/main.cpp
new file mode 100644
index 0000000..a85d421
--- /dev/null
+++ b/examples/qtgl/main.cpp
@@ -0,0 +1,30 @@
+#include "myqgl.h"
+
+#include <qapplication.h>
+#include <qvbox.h>
+#include <qpushbutton.h>
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+
+ if(!QGLFormat::hasOpenGL())
+ {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ QVBox *v = new QVBox;
+ QPushButton *b = new QPushButton("Show w3.bmp !", v);
+ MyQGL *gl = new MyQGL(v);
+
+ QVBox::connect(b, SIGNAL(clicked()), gl, SLOT(bind()));
+
+ v->setStretchFactor(gl, 1);
+
+ a.setMainWidget(v);
+ v->resize(512, 256);
+ v->show();
+
+ return a.exec();
+}
diff --git a/examples/qtgl/myqgl.cpp b/examples/qtgl/myqgl.cpp
new file mode 100644
index 0000000..42fe1da
--- /dev/null
+++ b/examples/qtgl/myqgl.cpp
@@ -0,0 +1,182 @@
+#include <qlibrary.h>
+#include <qapplication.h>
+#include <qfile.h>
+
+#include <GL/gl.h>
+
+#include "myqgl.h"
+
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/error.h"
+
+MyQGL::MyQGL(QWidget *parent, const char *name) : QGLWidget(parent, name), bits(0), w(0), h(0)
+{}
+
+MyQGL::~MyQGL()
+{}
+
+void MyQGL::initializeGL()
+{
+ qglClearColor(white);
+ glClearDepth(1.0f);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_ALPHA_TEST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glShadeModel(GL_FLAT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void MyQGL::resizeGL(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-width/2, width/2, -height/2, height/2, 0.1f, 100.0f);
+ gluLookAt(0,0,1, 0,0,0, 0,1,0);
+ glMatrixMode(GL_MODELVIEW);
+}
+
+void MyQGL::paintGL()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-w/2, h/2);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(w/2, h/2);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(w/2, -h/2);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(-w/2, -h/2);
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+}
+
+void MyQGL::loadImage()
+{
+ // try to load BMP library
+ QLibrary lib("/usr/lib/ksquirrel-libs/libkls_bmp.so");
+ lib.load();
+
+ // no such library
+ if(!lib.isLoaded())
+ {
+ qWarning("Can't load BMP library.");
+ qApp->quit();
+ }
+
+ int i = 0;
+ fmt_info finfo;
+ RGBA *image;
+ int current = 0;
+
+ // resolve neccessary functions
+ codec_create = (fmt_codec_base*(*)())lib.resolve("codec_create");
+ codec_destroy = (void (*)(fmt_codec_base*))lib.resolve("codec_destroy");
+
+ // library corrupted!
+ if(!codec_create || !codec_destroy)
+ {
+ qWarning("Library corrupted.");
+ lib.unload();
+ qApp->quit();
+ }
+
+ const char *s = "../w3.bmp";
+
+ // if the image doesn't exist
+ if(!QFile::exists(s))
+ {
+ qWarning("Can't find example image.");
+ lib.unload();
+ qApp->quit();
+ }
+
+ // OK, create decoder
+ codeK = codec_create();
+
+ // init library
+ i = codeK->read_init(s);
+
+ if(i != SQE_OK)
+ {
+ codeK->read_close();
+ return;
+ }
+
+ // move to the next image
+ i = codeK->read_next();
+
+ // save retrieved information
+ finfo = codeK->information();
+
+ if(i != SQE_OK)
+ {
+ codeK->read_close();
+ return;
+ }
+
+ image = (RGBA*)calloc(finfo.image[current].w * finfo.image[current].h, sizeof(RGBA));
+
+ if(!image)
+ {
+ codeK->read_close();
+ return;
+ }
+
+ memset(image, 255, finfo.image[current].w * finfo.image[current].h * sizeof(RGBA));
+
+ RGBA *scan;
+
+ // OK, let's decode the image line-by-line, pass-by-pass
+ for(int pass = 0;pass < finfo.image[current].passes;pass++)
+ {
+ codeK->read_next_pass();
+
+ for(int j = 0;j < finfo.image[current].h;j++)
+ {
+ scan = image + j * finfo.image[current].w;
+ codeK->read_scanline(scan);
+ }
+ }
+
+ // flip, if neccessary (BMP requires flipping)
+ if(finfo.image[current].needflip)
+ fmt_utils::flipv((char*)image, finfo.image[current].w * sizeof(RGBA), finfo.image[current].h);
+
+ // close library
+ codeK->read_close();
+
+ w = finfo.image[current].w;
+ h = finfo.image[current].h;
+ bits = image;
+}
+
+void MyQGL::bind()
+{
+ loadImage();
+
+ if(!bits)
+ return;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ // remember, that texture dimensions should be a power of two, e.g.
+ // 32, 64, 256, ...
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
+
+ updateGL();
+}
diff --git a/examples/qtgl/myqgl.h b/examples/qtgl/myqgl.h
new file mode 100644
index 0000000..be4707f
--- /dev/null
+++ b/examples/qtgl/myqgl.h
@@ -0,0 +1,40 @@
+#ifndef GLWIDGET_H
+#define GLWIDGET_H
+
+#include <qgl.h>
+
+#include <csetjmp>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class MyQGL : public QGLWidget
+{
+ Q_OBJECT
+
+ public:
+ MyQGL(QWidget *parent = 0, const char *name = 0);
+ ~MyQGL();
+
+ public slots:
+ void bind();
+
+ protected:
+ void initializeGL();
+ void paintGL();
+ void resizeGL(int,int);
+ void loadImage();
+
+ private:
+ void *bits;
+ unsigned int tex;
+ int w, h;
+ fmt_codec_base* (*codec_create)();
+ void (*codec_destroy)(fmt_codec_base*);
+
+ fmt_codec_base *codeK;
+
+};
+
+#endif
diff --git a/examples/qtgl/qtgl.pro b/examples/qtgl/qtgl.pro
new file mode 100644
index 0000000..83a68e4
--- /dev/null
+++ b/examples/qtgl/qtgl.pro
@@ -0,0 +1,12 @@
+######################################################################
+# Automatically generated by qmake (1.06c) Thu Mar 3 00:43:05 2005
+######################################################################
+
+TEMPLATE = app
+INCLUDEPATH += .
+INCLUDEPATH += ../../kernel/include
+
+# Input
+HEADERS += myqgl.h
+SOURCES += main.cpp myqgl.cpp ../../kernel/ksquirrel-libs/fmt_utils.cpp
+LIBS += -lGL -lGLU \ No newline at end of file
diff --git a/examples/w3.bmp b/examples/w3.bmp
new file mode 100644
index 0000000..d27f12d
--- /dev/null
+++ b/examples/w3.bmp
Binary files differ
diff --git a/kernel/Makefile.am b/kernel/Makefile.am
new file mode 100644
index 0000000..7f29cf2
--- /dev/null
+++ b/kernel/Makefile.am
@@ -0,0 +1,123 @@
+SUBDIRS = ksquirrel-libs kls_avs kls_bmp kls_cut kls_dds kls_fli kls_hdr kls_ico kls_jbig kls_koala kls_lif kls_mdl kls_mtv kls_pcx kls_pix kls_pnm kls_psd kls_pxr kls_ras kls_rawrgb kls_sct kls_sgi kls_sun kls_tga kls_wal kls_wbmp kls_xbm kls_xcf kls_xcur kls_xpm kls_png kls_psp
+
+EXTRA_DIST = generate link include/*.h include/ksquirrel-libs/*.h xpm/*.xpm
+
+if SQ_HAVE_CAMERA
+SUBDIRS += kls_camera
+endif
+
+if SQ_HAVE_JPEG
+SUBDIRS += kls_jpeg
+endif
+
+if SQ_HAVE_TIFF
+SUBDIRS += kls_tiff
+endif
+
+if SQ_HAVE_XWD
+SUBDIRS += kls_xwd
+endif
+
+if SQ_HAVE_WMF
+SUBDIRS += kls_wmf
+endif
+
+if SQ_HAVE_SVG
+SUBDIRS += kls_svg
+endif
+
+if SQ_HAVE_GIF
+SUBDIRS += kls_gif
+endif
+
+if SQ_HAVE_OPENEXR
+SUBDIRS += kls_openexr
+endif
+
+if SQ_HAVE_JPEG2000
+SUBDIRS += kls_jpeg2000
+endif
+
+if SQ_HAVE_TTF
+SUBDIRS += kls_ttf
+endif
+
+if SQ_HAVE_MNG
+SUBDIRS += kls_mng
+endif
+
+if SQ_HAVE_DJVU
+SUBDIRS += kls_djvu
+endif
+
+if SQ_HAVE_DXF
+SUBDIRS += kls_dxf
+endif
+
+if SQ_HAVE_NEO
+SUBDIRS += kls_neo
+endif
+
+if SQ_HAVE_LEAF
+SUBDIRS += kls_leaf
+endif
+
+if SQ_HAVE_PI1
+SUBDIRS += kls_pi1
+endif
+
+if SQ_HAVE_PI3
+SUBDIRS += kls_pi3
+endif
+
+if SQ_HAVE_XIM
+SUBDIRS += kls_xim
+endif
+
+if SQ_HAVE_UTAH
+SUBDIRS += kls_utah
+endif
+
+if SQ_HAVE_PICT
+SUBDIRS += kls_pict
+endif
+
+if SQ_HAVE_MAC
+SUBDIRS += kls_mac
+endif
+
+if SQ_HAVE_IFF
+SUBDIRS += kls_iff
+endif
+
+if SQ_HAVE_FIG
+SUBDIRS += kls_fig
+endif
+
+if SQ_HAVE_LJPEG
+SUBDIRS += kls_ljpeg
+endif
+
+if SQ_HAVE_DICOM
+SUBDIRS += kls_dicom
+endif
+
+if SQ_HAVE_EPS
+SUBDIRS += kls_eps
+endif
+
+# unstable/buggy codecs - for developers only
+if SQ_DEVEL
+SUBDIRS += kls_msp
+endif
+
+# install headers
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgincludedir)
+ $(INSTALL_HEADER) include/ksquirrel-libs/fileio.h $(DESTDIR)$(pkgincludedir)/fileio.h
+ $(INSTALL_HEADER) include/ksquirrel-libs/error.h $(DESTDIR)$(pkgincludedir)/error.h
+ $(INSTALL_HEADER) include/ksquirrel-libs/fmt_utils.h $(DESTDIR)$(pkgincludedir)/fmt_utils.h
+ $(INSTALL_HEADER) include/ksquirrel-libs/fmt_types.h $(DESTDIR)$(pkgincludedir)/fmt_types.h
+ $(INSTALL_HEADER) include/ksquirrel-libs/fmt_defs.h $(DESTDIR)$(pkgincludedir)/fmt_defs.h
+ $(INSTALL_HEADER) include/ksquirrel-libs/fmt_codec_base.h $(DESTDIR)$(pkgincludedir)/fmt_codec_base.h
+ $(INSTALL_HEADER) include/ksquirrel-libs/settings.h $(DESTDIR)$(pkgincludedir)/settings.h
diff --git a/kernel/generate b/kernel/generate
new file mode 100755
index 0000000..59e5ce5
--- /dev/null
+++ b/kernel/generate
@@ -0,0 +1,223 @@
+#!/bin/sh
+
+# Generate new development directory for image format
+#
+# Usage:
+# $ ./generate <format>
+#
+
+
+name=$1
+mkdir $name
+mkdir include > /dev/null 2>&1
+cd $name
+
+cat << EOF > Makefile.am
+INCLUDES = -I../include
+
+lib_LTLIBRARIES = lib${name}.la
+
+lib${name}_la_SOURCES = fmt_codec_${name}.cpp fmt_codec_${name}_defs.h
+
+lib${name}_la_LDFLAGS =
+EOF
+
+cat << EOF > ../include/fmt_codec_${name}.h
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_${name}_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_${name}_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ // define variables you need here
+};
+
+#endif
+EOF
+
+cat << EOF > fmt_codec_${name}_defs.h
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_${name}
+#define KSQUIRREL_CODEC_DEFS_${name}
+
+// define constants here
+
+#endif
+EOF
+
+cat << EOF > fmt_codec_${name}.cpp
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_${name}_defs.h"
+#include "fmt_codec_${name}.h"
+
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_${name}.xpm"
+EOF
+
+cat << EOF >> fmt_codec_${name}.cpp
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "";
+ o->filter = "*. ";
+ o->mime = "";
+ o->pixmap = codec_${name};
+ o->config = "";
+ o->readable = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->canbemultiple = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+/*
+ image.w =
+ image.h =
+ image.bpp =
+*/
+
+ image.compression = "";
+ image.colorspace = "";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ RGBA rgba;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
+EOF
+
+echo
+echo "All done!"
+echo
+echo "Don't forget to insert your copyrights and edit Makefile.am"
+echo
diff --git a/kernel/include/fmt_codec_avs.h b/kernel/include/fmt_codec_avs.h
new file mode 100644
index 0000000..8bc4f9f
--- /dev/null
+++ b/kernel/include/fmt_codec_avs.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_avs_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_avs_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ WRITE_CODEC_DECLARATIONS
+
+ private:
+ // define variables you need here
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_bmp.h b/kernel/include/fmt_codec_bmp.h
new file mode 100644
index 0000000..e49f351
--- /dev/null
+++ b/kernel/include/fmt_codec_bmp.h
@@ -0,0 +1,46 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_BMP_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_BMP_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ WRITE_CODEC_DECLARATIONS
+
+ private:
+ RGB pal[256];
+ s32 pal_entr;
+ u16 filler;
+ BITMAPFILE_HEADER bfh;
+ BITMAPINFO_HEADER bih;
+ s32 m_FILLER;
+ BITMAPFILE_HEADER m_bfh;
+ BITMAPINFO_HEADER m_bih;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_cd_func.h b/kernel/include/fmt_codec_cd_func.h
new file mode 100644
index 0000000..da38f56
--- /dev/null
+++ b/kernel/include/fmt_codec_cd_func.h
@@ -0,0 +1,35 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_create_destroy_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_create_destroy_H
+
+extern "C" fmt_codec_base* codec_create()
+{
+ return (new fmt_codec);
+}
+
+extern "C" void codec_destroy(fmt_codec_base *p)
+{
+ delete p;
+}
+
+#endif
diff --git a/kernel/include/fmt_codec_cut.h b/kernel/include/fmt_codec_cut.h
new file mode 100644
index 0000000..df8f099
--- /dev/null
+++ b/kernel/include/fmt_codec_cut.h
@@ -0,0 +1,38 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_CUT_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_CUT_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ RGB pal[256];
+ u8 *bits;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_dds.h b/kernel/include/fmt_codec_dds.h
new file mode 100644
index 0000000..6def2c5
--- /dev/null
+++ b/kernel/include/fmt_codec_dds.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2007 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_dds_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_dds_H
+
+#include "dds.h"
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ DDSINFO dds;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_fli.h b/kernel/include/fmt_codec_fli.h
new file mode 100644
index 0000000..cea637c
--- /dev/null
+++ b/kernel/include/fmt_codec_fli.h
@@ -0,0 +1,42 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_FLI_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_FLI_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ bool skip_flood(ifstreamK &s);
+
+ private:
+ FLICHEADER flic;
+ RGB pal[768];
+ u8 **buf;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_gif.h b/kernel/include/fmt_codec_gif.h
new file mode 100644
index 0000000..f04077b
--- /dev/null
+++ b/kernel/include/fmt_codec_gif.h
@@ -0,0 +1,45 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_GIF_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_GIF_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ GifFileType *gif;
+ GifRecordType record;
+ GifByteType *Extension;
+ u8 *buf;
+ RGBA *saved;
+ s32 i, j, Error, Row, Col, Width, Height, lastRow, lastCol, lastWidth, lastHeight, ExtCode, Count,
+ transIndex, Lines_h, curLine, linesz, disposal, lastDisposal, currentImage, currentPass;
+ RGBA **Lines, back, **Last;
+ ColorMapObject *map;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_hdr.h b/kernel/include/fmt_codec_hdr.h
new file mode 100644
index 0000000..c6759ed
--- /dev/null
+++ b/kernel/include/fmt_codec_hdr.h
@@ -0,0 +1,42 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_hdr_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_hdr_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ bool read_scan(u8 *s, const s32 w);
+ bool getHdrHead();
+
+ private:
+ u8 *scanline;
+ hdr_header hdr;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_ico.h b/kernel/include/fmt_codec_ico.h
new file mode 100644
index 0000000..73cbaa1
--- /dev/null
+++ b/kernel/include/fmt_codec_ico.h
@@ -0,0 +1,43 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_ICO_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_ICO_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ u8 *bAND;
+ ICO_HEADER ifh;
+ ICO_DIRENTRY *ide;
+ BITMAPINFO_HEADER bih;
+ s32 pixel;
+ RGB pal[256];
+ s32 pal_entr;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_iff.h b/kernel/include/fmt_codec_iff.h
new file mode 100644
index 0000000..62012f9
--- /dev/null
+++ b/kernel/include/fmt_codec_iff.h
@@ -0,0 +1,41 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_IFF_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_IFF_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ RGB *pal;
+ s32 pal_entr;
+ CHUNK_BMHD bmhd;
+ u8 **tile;
+ u8 *dline;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_jbig.h b/kernel/include/fmt_codec_jbig.h
new file mode 100644
index 0000000..d2429bd
--- /dev/null
+++ b/kernel/include/fmt_codec_jbig.h
@@ -0,0 +1,34 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_jbig_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_jbig_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_jpeg.h b/kernel/include/fmt_codec_jpeg.h
new file mode 100644
index 0000000..b54e7b9
--- /dev/null
+++ b/kernel/include/fmt_codec_jpeg.h
@@ -0,0 +1,48 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_JPEG_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_JPEG_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ WRITE_CODEC_DECLARATIONS
+
+ private:
+ struct jpeg_decompress_struct cinfo;
+ struct my_error_mgr jerr;
+ JSAMPARRAY buffer;
+ FILE *fptr;
+
+ FILE *m_fptr;
+ struct jpeg_compress_struct m_cinfo;
+ struct jpeg_error_mgr m_jerr;
+ JSAMPROW row_pointer;
+ bool zerror;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_jpeg2000.h b/kernel/include/fmt_codec_jpeg2000.h
new file mode 100644
index 0000000..23e9ac1
--- /dev/null
+++ b/kernel/include/fmt_codec_jpeg2000.h
@@ -0,0 +1,51 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_jpeg2000_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_jpeg2000_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+typedef struct
+{
+ jas_image_t *image;
+ s32 cmptlut[MAXCMPTS];
+ jas_image_t *altimage;
+ jas_matrix_t *data[3];
+ jas_seqent_t *d[3];
+
+} gs_t;
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ bool convert_colorspace();
+
+ private:
+ gs_t gs;
+ jas_stream_t *in;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_koala.h b/kernel/include/fmt_codec_koala.h
new file mode 100644
index 0000000..24a55b4
--- /dev/null
+++ b/kernel/include/fmt_codec_koala.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_koala_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_koala_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ koala_t koala;
+ u8 pixel_mask[4], pixel_displ[4], foundcolor;
+ s32 index, pixel, colorindex;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_lif.h b/kernel/include/fmt_codec_lif.h
new file mode 100644
index 0000000..489b057
--- /dev/null
+++ b/kernel/include/fmt_codec_lif.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_lif_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_lif_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ RGBA pal[256];
+ lif_header lif;
+ s32 bytes;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_mac.h b/kernel/include/fmt_codec_mac.h
new file mode 100644
index 0000000..f65dcaf
--- /dev/null
+++ b/kernel/include/fmt_codec_mac.h
@@ -0,0 +1,37 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_mac_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_mac_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ u8 bytes[72], byte[8];
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_mdl.h b/kernel/include/fmt_codec_mdl.h
new file mode 100644
index 0000000..c24134b
--- /dev/null
+++ b/kernel/include/fmt_codec_mdl.h
@@ -0,0 +1,40 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_mdl_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_mdl_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ TEX_HEAD tex;
+ RGB pal[256];
+ s32 numtex, texoff, texdataoff;
+ fstream::pos_type opos;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_mng.h b/kernel/include/fmt_codec_mng.h
new file mode 100644
index 0000000..ff4b546
--- /dev/null
+++ b/kernel/include/fmt_codec_mng.h
@@ -0,0 +1,51 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_mng_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_mng_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+struct mngstuff;
+
+struct _priv
+{
+ RGBA *frame;
+ int w, ms;
+
+}priv;
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ mngstuff *mymng;
+ mng_handle mng;
+ s32 total;
+
+ public:
+ _priv priv;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_msp.h b/kernel/include/fmt_codec_msp.h
new file mode 100644
index 0000000..5ef6f7c
--- /dev/null
+++ b/kernel/include/fmt_codec_msp.h
@@ -0,0 +1,41 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_msp_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_msp_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ msp_header msp;
+ std::vector<u16> scanmap;
+ s32 version;
+ u8 *bytes;
+ u8 byte[8];
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_mtv.h b/kernel/include/fmt_codec_mtv.h
new file mode 100644
index 0000000..77062a3
--- /dev/null
+++ b/kernel/include/fmt_codec_mtv.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_mtv_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_mtv_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ WRITE_CODEC_DECLARATIONS
+
+ private:
+ // define variables you need here
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_openexr.h b/kernel/include/fmt_codec_openexr.h
new file mode 100644
index 0000000..a08e370
--- /dev/null
+++ b/kernel/include/fmt_codec_openexr.h
@@ -0,0 +1,45 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_openexr_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_openexr_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+#include <ImfRgbaFile.h>
+#include <ImfArray.h>
+
+using namespace Imf;
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ Array2D<Rgba> *pixels;
+ std::string file, ref;
+ RgbaOutputFile *out;
+ Rgba *hs;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_pcx.h b/kernel/include/fmt_codec_pcx.h
new file mode 100644
index 0000000..4daedb6
--- /dev/null
+++ b/kernel/include/fmt_codec_pcx.h
@@ -0,0 +1,40 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_PCX_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_PCX_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ PCX_HEADER pfh;
+ s16 TotalBytesLine;
+ RGB pal[256];
+ s32 pal_entr;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_pix.h b/kernel/include/fmt_codec_pix.h
new file mode 100644
index 0000000..58c23a1
--- /dev/null
+++ b/kernel/include/fmt_codec_pix.h
@@ -0,0 +1,34 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_PIX_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_PIX_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_png.h b/kernel/include/fmt_codec_png.h
new file mode 100644
index 0000000..2051187
--- /dev/null
+++ b/kernel/include/fmt_codec_png.h
@@ -0,0 +1,63 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_PNG_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_PNG_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+#ifdef CODEC_ANOTHER
+ virtual void fill_default_settings();
+#endif
+
+#ifdef CODEC_PNG
+ WRITE_CODEC_DECLARATIONS
+#endif
+
+ private:
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_uint_32 width, height, number_passes;
+ s32 color_type;
+ png_bytep *cur, *prev, *frame;
+ FILE *fptr;
+ s32 bit_depth, interlace_type;
+ s32 frames;
+ fmt_image img;
+
+ png_uint_32 next_frame_width, next_frame_height, next_frame_x_offset, next_frame_y_offset;
+ png_uint_16 next_frame_delay_num, next_frame_delay_den;
+ png_byte next_frame_dispose_op, next_frame_blend_op;
+
+ FILE *m_fptr;
+ png_structp m_png_ptr;
+ png_infop m_info_ptr;
+ png_bytep m_row_pointer;
+ bool zerror, m_zerror;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_pnm.h b/kernel/include/fmt_codec_pnm.h
new file mode 100644
index 0000000..d2e9c60
--- /dev/null
+++ b/kernel/include/fmt_codec_pnm.h
@@ -0,0 +1,48 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_PNM_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_PNM_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+#ifdef CODEC_ANOTHER
+ virtual void fill_default_settings();
+#endif
+
+#ifdef CODEC_PNM
+ WRITE_CODEC_DECLARATIONS
+#endif
+
+ private:
+ s32 pnm;
+ FILE *fptr;
+ s8 format[10];
+ double koeff;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_psd.h b/kernel/include/fmt_codec_psd.h
new file mode 100644
index 0000000..94ee1f2
--- /dev/null
+++ b/kernel/include/fmt_codec_psd.h
@@ -0,0 +1,41 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_PSD_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_PSD_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ u32 width, height;
+ u16 channels, depth, mode, compression;
+ RGBA **last;
+ u8 *L;
+ RGB pal[256];
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_psp.h b/kernel/include/fmt_codec_psp.h
new file mode 100644
index 0000000..730269b
--- /dev/null
+++ b/kernel/include/fmt_codec_psp.h
@@ -0,0 +1,53 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_psp_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_psp_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ bool iGetPspHead();
+ bool iCheckPsp();
+ bool ReadGenAttributes();
+ bool ParseChunks();
+ bool ReadLayerBlock();
+ bool ReadAlphaBlock();
+ ILubyte *GetChannel();
+ bool UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen);
+ bool ReadPalette();
+
+ private:
+ GENATT_CHUNK AttChunk;
+ PSPHEAD Header;
+ ILuint NumChannels;
+ ILubyte **Channels;
+ ILubyte *Alpha;
+ RGBA *pal;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_pxr.h b/kernel/include/fmt_codec_pxr.h
new file mode 100644
index 0000000..af1a9a0
--- /dev/null
+++ b/kernel/include/fmt_codec_pxr.h
@@ -0,0 +1,34 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_pxr_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_pxr_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_ras.h b/kernel/include/fmt_codec_ras.h
new file mode 100644
index 0000000..6c60ab7
--- /dev/null
+++ b/kernel/include/fmt_codec_ras.h
@@ -0,0 +1,43 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_RAS_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_RAS_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ RGB pal[256];
+ RAS_HEADER rfh;
+ bool rle, isRGB;
+ u16 fill;
+ u8 fillchar;
+ u16 linelength;
+ u8 *buf;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_rawrgb.h b/kernel/include/fmt_codec_rawrgb.h
new file mode 100644
index 0000000..db756e2
--- /dev/null
+++ b/kernel/include/fmt_codec_rawrgb.h
@@ -0,0 +1,40 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_rawrgb_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_rawrgb_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ WRITE_CODEC_DECLARATIONS
+
+ private:
+ // define variables you need here
+};
+
+#endif
+
diff --git a/kernel/include/fmt_codec_sct.h b/kernel/include/fmt_codec_sct.h
new file mode 100644
index 0000000..416a780
--- /dev/null
+++ b/kernel/include/fmt_codec_sct.h
@@ -0,0 +1,37 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_sct_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_sct_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ sct_header sct;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_sgi.h b/kernel/include/fmt_codec_sgi.h
new file mode 100644
index 0000000..ce65fb7
--- /dev/null
+++ b/kernel/include/fmt_codec_sgi.h
@@ -0,0 +1,40 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_SGI_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_SGI_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ u32 *starttab, *lengthtab;
+ SGI_HEADER sfh;
+ s32 rle_row;
+ s8 *channel[4];
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_sun.h b/kernel/include/fmt_codec_sun.h
new file mode 100644
index 0000000..3fc730b
--- /dev/null
+++ b/kernel/include/fmt_codec_sun.h
@@ -0,0 +1,38 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_sun_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_sun_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ u32 validbits;
+};
+
+#endif
+
diff --git a/kernel/include/fmt_codec_tga.h b/kernel/include/fmt_codec_tga.h
new file mode 100644
index 0000000..535d108
--- /dev/null
+++ b/kernel/include/fmt_codec_tga.h
@@ -0,0 +1,40 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_TGA_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_TGA_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ s32 pal_entr;
+ RGB pal[256];
+ TGA_FILEHEADER tfh;
+ bool fliph;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_tiff.h b/kernel/include/fmt_codec_tiff.h
new file mode 100644
index 0000000..713a8d6
--- /dev/null
+++ b/kernel/include/fmt_codec_tiff.h
@@ -0,0 +1,46 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_TIFF_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_TIFF_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+#include <map>
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ WRITE_CODEC_DECLARATIONS
+
+ void fill_default_settings();
+
+ private:
+ TIFF *ftiff, *out;
+ TIFFRGBAImage img;
+ s32 dircount, line, pages;
+ std::map<s32, std::string> compr;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_ttf.h b/kernel/include/fmt_codec_ttf.h
new file mode 100644
index 0000000..d97df91
--- /dev/null
+++ b/kernel/include/fmt_codec_ttf.h
@@ -0,0 +1,34 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_ttf_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_ttf_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_utah.h b/kernel/include/fmt_codec_utah.h
new file mode 100644
index 0000000..5076afb
--- /dev/null
+++ b/kernel/include/fmt_codec_utah.h
@@ -0,0 +1,38 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_utah_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_utah_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ UTAH_HEADER utah;
+};
+
+#endif
+
diff --git a/kernel/include/fmt_codec_wal.h b/kernel/include/fmt_codec_wal.h
new file mode 100644
index 0000000..5496bdc
--- /dev/null
+++ b/kernel/include/fmt_codec_wal.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_wal_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_wal_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ wal_header wal;
+ s32 neww, newh;
+ u8 *bits;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_wbmp.h b/kernel/include/fmt_codec_wbmp.h
new file mode 100644
index 0000000..cdaa382
--- /dev/null
+++ b/kernel/include/fmt_codec_wbmp.h
@@ -0,0 +1,49 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_wbmp_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_wbmp_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class Wbmp;
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ s32 putmbi(s32 i, ofstreamK &f);
+ s32 getmbi(ifstreamK &f);
+ s32 skipheader(ifstreamK &f);
+
+ Wbmp* createwbmp(s32 width, s32 height, s32 color);
+
+ s32 writewbmp(Wbmp *wbmp, ofstreamK &out);
+
+ private:
+ Wbmp wbmp;
+};
+
+#endif
+
diff --git a/kernel/include/fmt_codec_wmf.h b/kernel/include/fmt_codec_wmf.h
new file mode 100644
index 0000000..aa5d373
--- /dev/null
+++ b/kernel/include/fmt_codec_wmf.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_wmf_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_wmf_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ u8 *buf;
+ s32 w, h;
+};
+
+#endif
+
diff --git a/kernel/include/fmt_codec_xbm.h b/kernel/include/fmt_codec_xbm.h
new file mode 100644
index 0000000..5a36dbf
--- /dev/null
+++ b/kernel/include/fmt_codec_xbm.h
@@ -0,0 +1,40 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_XBM_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_XBM_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ FILE *fptr;
+ RGB pal[2];
+ s32 lscan;
+ s32 version;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_xcur.h b/kernel/include/fmt_codec_xcur.h
new file mode 100644
index 0000000..6f4fd16
--- /dev/null
+++ b/kernel/include/fmt_codec_xcur.h
@@ -0,0 +1,43 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_XCUR_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_XCUR_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ s32 currentToc;
+ bool lastToc;
+
+ XCUR_HEADER xcur_h;
+ XCUR_CHUNK_DESC *tocs;
+ XCUR_CHUNK_HEADER xcur_chunk;
+ XCUR_CHUNK_IMAGE xcur_im;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_xpm.h b/kernel/include/fmt_codec_xpm.h
new file mode 100644
index 0000000..277f438
--- /dev/null
+++ b/kernel/include/fmt_codec_xpm.h
@@ -0,0 +1,44 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_XPM_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_XPM_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ void fillmap();
+ RGBA hex2rgb(const s8 *hex);
+
+ private:
+ s32 numcolors;
+ s32 cpp;
+ std::map<std::string, RGBA> named;
+ std::map<std::string, RGBA> file;
+};
+
+#endif
diff --git a/kernel/include/fmt_codec_xwd.h b/kernel/include/fmt_codec_xwd.h
new file mode 100644
index 0000000..690afa7
--- /dev/null
+++ b/kernel/include/fmt_codec_xwd.h
@@ -0,0 +1,38 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_XWD_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_XWD_H
+
+#include "ksquirrel-libs/fmt_codec_base.h"
+
+class fmt_codec : public fmt_codec_base
+{
+ public:
+
+ BASE_CODEC_DECLARATIONS
+
+ private:
+ s32 pal_entr, filler;
+ RGB *pal;
+};
+
+#endif
diff --git a/kernel/include/ksquirrel-libs/error.h b/kernel/include/ksquirrel-libs/error.h
new file mode 100644
index 0000000..bfeec9e
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/error.h
@@ -0,0 +1,49 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net) libraries
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_ERROR_CODES_H
+#define KSQUIRREL_LIBS_ERROR_CODES_H
+
+
+///////////////////////////////////
+// //
+// Error codes for libraries //
+// //
+///////////////////////////////////
+
+
+#define SQE_NOTOK 0
+#define SQE_OK 1
+
+#define SQE_R_NOFILE 1024
+#define SQE_R_BADFILE 1025
+#define SQE_R_NOMEMORY 1026
+#define SQE_R_NOTSUPPORTED 1027
+#define SQE_R_WRONGDIM 1028
+
+#define SQE_W_NOFILE 1029
+#define SQE_W_NOMEMORY SQE_R_NOMEMORY
+#define SQE_W_NOTSUPPORTED 1032
+#define SQE_W_ERROR 1033
+#define SQE_W_WRONGPARAMS 1034
+#define SQE_W_WRONGDIM SQE_R_WRONGDIM
+
+#endif
diff --git a/kernel/include/ksquirrel-libs/fileio.h b/kernel/include/ksquirrel-libs/fileio.h
new file mode 100644
index 0000000..3bf3921
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/fileio.h
@@ -0,0 +1,73 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_FIO_H
+#define KSQUIRREL_LIBS_FIO_H
+
+#include <fstream>
+
+using namespace std;
+
+#include <ksquirrel-libs/fmt_types.h>
+
+////////////////////////////////
+// //
+// Binary-oriented file i/o //
+// //
+////////////////////////////////
+
+
+// read binary data
+class ifstreamK : public ifstream
+{
+ public:
+ ifstreamK();
+
+ // read 'size' bytes of binary data and store it into 'data'.
+ // return true if reading was successful, and false otherwise
+ bool readK(void *data, int size);
+
+ // read string from file
+ bool getS(char *, const int);
+
+ // read ascii hex value from file
+ bool readCHex(u32 &hex);
+
+ // big-endian-oriented reading
+ bool be_getchar(u8 *c);
+ bool be_getshort(u16 *s);
+ bool be_getlong(u32 *l);
+
+ void close();
+};
+
+// write binary data
+class ofstreamK : public ofstream
+{
+ public:
+ ofstreamK();
+
+ bool writeK(void *data, int size);
+
+ void close();
+};
+
+#endif
diff --git a/kernel/include/ksquirrel-libs/fmt_codec_base.h b/kernel/include/ksquirrel-libs/fmt_codec_base.h
new file mode 100644
index 0000000..cae04ea
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/fmt_codec_base.h
@@ -0,0 +1,258 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_H
+#define KSQUIRREL_LIBS_CLASS_DEFINITION_H
+
+#include <ksquirrel-libs/fmt_defs.h>
+#include <ksquirrel-libs/fileio.h>
+#include <ksquirrel-libs/settings.h>
+
+//////////////////////////////////
+// //
+// Base class for all //
+// codecs //
+// //
+//////////////////////////////////
+
+
+class fmt_codec_base
+{
+ public:
+ fmt_codec_base()
+ {}
+
+ virtual ~fmt_codec_base()
+ {}
+
+ // version of the library, e.g. "1.2.2", etc.
+ //
+ // tell clients that fmt_codec_base couldn't be
+ // instantianted
+ virtual void options(codec_options *) = 0;
+
+ // return file extension for a given bpp
+ virtual std::string extension(const s32 bpp);
+
+ /*
+ * read methods
+ */
+
+ // fmt_read_init: do what you need before decoding
+ virtual s32 read_init(const std::string &file);
+
+ // fmt_read_next: seek to correct file offset, do other initialization stuff.
+ // this method should be (and will be) called before image is about to
+ // be decoded.
+ virtual s32 read_next();
+
+ // fmt_read_next_pass: do somethimg important before the next pass
+ // will be decoded (usually do nothing, if the image has only 1 pass (like BMP, PCX ...),
+ // or adjust variables if the image is interlaced, with passes > 1 (like GIF, PNG))
+ virtual s32 read_next_pass();
+
+ // fmt_readscanline: read one scanline from file
+ virtual s32 read_scanline(RGBA *scan);
+
+ // fmt_read_close: close all handles, free memory, etc.
+ virtual void read_close();
+
+ /*
+ * write methods
+ */
+
+ // fmt_getwriteoptions: return write options for this image format
+ virtual void getwriteoptions(fmt_writeoptionsabs *);
+
+ // fmt_write_init: init writing
+ virtual s32 write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt);
+
+ virtual s32 write_next();
+
+ virtual s32 write_next_pass();
+
+ // fmt_write_scanline: write scanline
+ virtual s32 write_scanline(RGBA *scan);
+
+ // fmt_write_close: close writing(close descriptors, free memory, etc.)
+ virtual void write_close();
+
+ fmt_info information() const;
+
+ fmt_image* image(const int index);
+
+ void addmeta(const fmt_metaentry &m);
+
+ void settempfile(const std::string &t);
+
+ // fill fmt_settings with values
+ void set_settings(const fmt_settings &sett);
+
+ fmt_settings settings() const;
+
+ virtual void fill_default_settings()
+ {}
+
+ protected:
+ // image index in finfo.image
+ s32 currentImage;
+
+ // fmt_info structure
+ fmt_info finfo;
+
+ // input stream
+ ifstreamK frs;
+
+ // output stream
+ ofstreamK fws;
+
+ // some additional error checkers
+ bool read_error, write_error;
+
+ // line and layer indexes - needed by some
+ // interlaced or layered images
+ s32 line, layer;
+
+ // error code
+ s32 write_error_code;
+
+ // write options
+ fmt_writeoptions writeopt;
+
+ // saved fmt_image
+ fmt_image writeimage;
+
+ // path to temporary file
+ // should be set by the highlevel application
+ // with settempfile()
+ std::string tmp;
+
+ fmt_settings m_settings;
+};
+
+inline
+fmt_settings fmt_codec_base::settings() const
+{
+ return m_settings;
+}
+
+inline
+void fmt_codec_base::set_settings(const fmt_settings &sett)
+{
+ m_settings = sett;
+}
+
+inline
+fmt_info fmt_codec_base::information() const
+{
+ return finfo;
+}
+
+inline
+fmt_image* fmt_codec_base::image(const int index)
+{
+ return &finfo.image[index];
+}
+
+inline
+void fmt_codec_base::addmeta(const fmt_metaentry &m)
+{
+ finfo.meta.push_back(m);
+}
+
+inline
+void fmt_codec_base::settempfile(const std::string &t)
+{
+ tmp = t;
+}
+
+inline
+std::string fmt_codec_base::extension(const s32)
+{
+ return std::string("");
+}
+
+inline
+s32 fmt_codec_base::read_init(const std::string &)
+{ return 1; }
+
+inline
+s32 fmt_codec_base::read_next()
+{ return 1; }
+
+inline
+s32 fmt_codec_base::read_next_pass()
+{ return 1; }
+
+inline
+s32 fmt_codec_base::read_scanline(RGBA *)
+{ return 1; }
+
+inline
+void fmt_codec_base::read_close()
+{}
+
+inline
+void fmt_codec_base::getwriteoptions(fmt_writeoptionsabs *)
+{}
+
+inline
+s32 fmt_codec_base::write_init(const std::string &, const fmt_image &, const fmt_writeoptions &)
+{ return 1; }
+
+inline
+s32 fmt_codec_base::write_next()
+{ return 1; }
+
+inline
+s32 fmt_codec_base::write_next_pass()
+{ return 1; }
+
+inline
+s32 fmt_codec_base::write_scanline(RGBA *)
+{ return 1; }
+
+inline
+void fmt_codec_base::write_close()
+{}
+
+#define BASE_CODEC_DECLARATIONS \
+ fmt_codec(); \
+ ~fmt_codec(); \
+ \
+ virtual void options(codec_options *o); \
+ virtual s32 read_init(const std::string &file);\
+ virtual s32 read_next(); \
+ virtual s32 read_next_pass(); \
+ virtual s32 read_scanline(RGBA *scan); \
+ virtual void read_close();
+
+#define WRITE_CODEC_DECLARATIONS \
+ virtual std::string extension(const s32 bpp); \
+ virtual void getwriteoptions(fmt_writeoptionsabs *); \
+ virtual s32 write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt); \
+ virtual s32 write_next(); \
+ virtual s32 write_next_pass(); \
+ virtual s32 write_scanline(RGBA *scan); \
+ virtual void write_close();
+
+#endif
+
diff --git a/kernel/include/ksquirrel-libs/fmt_defs.h b/kernel/include/ksquirrel-libs/fmt_defs.h
new file mode 100644
index 0000000..a2bbd6c
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/fmt_defs.h
@@ -0,0 +1,242 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_DEFS_H
+#define KSQUIRREL_LIBS_DEFS_H
+
+#include <vector>
+#include <string>
+
+#include <ksquirrel-libs/fmt_types.h>
+
+struct codec_options
+{
+ std::string version,
+ name,
+ filter,
+ mime,
+ mimetype,
+ config;
+
+ void *pixmap;
+
+ bool readable,
+ canbemultiple,
+ writestatic,
+ writeanimated,
+ needtempfile;
+};
+
+/* Metainfo support */
+
+struct fmt_metaentry
+{
+ std::string group;
+ std::string data;
+};
+
+/* RGBA and RGB pixels */
+
+struct RGBA
+{
+ RGBA() : r(0), g(0), b(0), a(0)
+ {}
+
+ RGBA(s32 r1, s32 g1, s32 b1, s32 a1) : r(r1), g(g1), b(b1), a(a1)
+ {}
+
+ u8 r;
+ u8 g;
+ u8 b;
+ u8 a;
+
+}PACKED;
+
+struct RGB
+{
+ RGB() : r(0), g(0), b(0)
+ {}
+
+ RGB(s32 r1, s32 g1, s32 b1) : r(r1), g(g1), b(b1)
+ {}
+
+ u8 r;
+ u8 g;
+ u8 b;
+
+}PACKED;
+
+/* Image decription */
+struct fmt_image
+{
+ fmt_image() : w(0), h(0), bpp(0), hasalpha(false), needflip(false), delay(0),
+ interlaced(false), passes(1)
+ {}
+
+ // width and height
+ s32 w;
+ s32 h;
+
+ // bit depth
+ s32 bpp;
+
+ // has alpha channel ?
+ bool hasalpha;
+
+ // need to be flipped ?
+ bool needflip;
+
+ // if it's a frame in animated sequence,
+ // 'delay' will define a delay time
+ s32 delay;
+
+ // interlaced or normal ?
+ bool interlaced;
+
+ // if interlaced, 'passes' stores the number
+ // of passes. if no, passes should be 1
+ s32 passes;
+
+ // some useful info about image.
+ // this is a replacement for 'dump' in older versions of ksquirrel-libs
+ // --------------------------------------------------------------------
+
+ // color space (RGB, RGBA, CMYK, LAB ...)
+ std::string colorspace;
+
+ // compression type (RLE, JPEG, Deflate ...)
+ std::string compression;
+
+ // palette types
+ enum fmt_palette { monochrome = 1, indexed4 = 2, indexed8 = 4, indexed15 = 8,
+ indexed16 = 16, pure24 = 32, pure32 = 64, internal = 128 };
+
+ // palette, if exists
+ std::vector<RGB> palette;
+};
+
+/* General description */
+struct fmt_info
+{
+ fmt_info() : animated(false)
+ {}
+
+ /*
+ * TODO: make 'image' and 'meta' implicitly shared ?
+ */
+
+ // array of images
+ std::vector<fmt_image> image;
+
+ // array of metainfo entries
+ std::vector<fmt_metaentry> meta;
+
+ // animated or static
+ bool animated;
+};
+
+/* Internal cmpression.
+ E.g. compression_level will be
+ passed to internal routines,
+ No compression RLE compression for ex. in libjpeg, libpng.
+*/
+enum fmt_compression { CompressionNo = 1, CompressionRLE = 2, CompressionInternal = 4 };
+/* Note: if the image can be compressed
+ with RLE encoding and with only RLE
+ encoding, compression_scheme should be
+ CompressionInternal
+*/
+
+/* Write options for image format */
+struct fmt_writeoptionsabs
+{
+ // can be interlaced ?
+ bool interlaced;
+
+ // if interlaced, this value should store preferred number of passes.
+ s32 passes;
+
+ // if the image should be flipped before writing
+ bool needflip;
+
+ // with which compression it can be encoded ?
+ // for example: CompressionNo | CompressionRLE.
+ // it means, that image can be encoded with RLE
+ // method or can be saved uncompressed.
+ s32 compression_scheme;
+
+ // minimum compression level, maximum and default
+ // For example, JPEG library has minimum = 0,
+ // maximum = 100 and default = 25.
+ s32 compression_min, compression_max, compression_def;
+
+ // with which bit depth it can be encoded ?
+ // 1 means support of this bit depth,
+ // and 0 otherwise. This param cann't be null.
+ //
+ // bits 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+ // bit depth 32 24 16 15 8 4 1
+ u8 palette_flags;
+
+}PACKED;
+
+/* this information will be passed to writing function */
+struct fmt_writeoptions
+{
+ // write interlaced image or normal ?
+ bool interlaced;
+
+ // with which compression encode the image ?
+ fmt_compression compression_scheme;
+
+ // compression level
+ s32 compression_level;
+
+ // has alpha channel ?
+ // If no, A channel in RGBA image will be ignored
+ bool alpha;
+
+ s32 bitdepth;
+
+}PACKED;
+
+#if defined SQ_NEED_OPERATOR_RGBA_RGBA
+static s32 operator== (const RGBA &rgba1, const RGBA &rgba2)
+{
+ return (rgba1.r == rgba2.r && rgba1.g == rgba2.g && rgba1.b == rgba2.b && rgba1.a == rgba2.a);
+}
+#endif
+
+#if defined SQ_NEED_OPERATOR_RGB_RGBA
+static s32 operator== (const RGB &rgb, const RGBA &rgba)
+{
+ return (rgb.r == rgba.r && rgb.g == rgba.g && rgb.b == rgba.b);
+}
+#endif
+
+#if defined SQ_NEED_OPERATOR_RGBA_RGB
+static s32 operator== (const RGBA &rgba, const RGB &rgb)
+{
+ return (rgba.r == rgb.r && rgba.g == rgb.g && rgba.b == rgb.b);
+}
+#endif
+
+#endif
diff --git a/kernel/include/ksquirrel-libs/fmt_types.h b/kernel/include/ksquirrel-libs/fmt_types.h
new file mode 100644
index 0000000..75b6f02
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/fmt_types.h
@@ -0,0 +1,36 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_TYPES_H
+#define KSQUIRREL_LIBS_TYPES_H
+
+typedef char s8;
+typedef unsigned char u8;
+
+typedef short s16;
+typedef unsigned short u16;
+
+typedef int s32;
+typedef unsigned int u32;
+
+#define PACKED __attribute__ ((packed))
+
+#endif
diff --git a/kernel/include/ksquirrel-libs/fmt_utils.h b/kernel/include/ksquirrel-libs/fmt_utils.h
new file mode 100644
index 0000000..1ab42e3
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/fmt_utils.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_UTILS_H
+#define KSQUIRREL_LIBS_UTILS_H
+
+#include <string>
+
+using namespace std;
+
+#include <ksquirrel-libs/fmt_types.h>
+
+struct RGBA;
+
+////////////////////////
+// //
+// Helper namespace //
+// //
+////////////////////////
+
+
+namespace fmt_utils
+{
+ void fillAlpha(RGBA *scan, int w, u8 value = 255);
+
+ // flip the image vertically
+ // usually BMP, SGI (or some other formats) need to be flipped
+ void flipv(s8 *image, s32 bytes_w, s32 h);
+
+ // flip the image horizontally
+ void fliph(s8 *image, s32 w, s32 h, s32 bpp);
+
+ // Big endian to Little endian conversion
+ u16 konvertWord(u16 a);
+ u32 konvertLong(u32 a);
+
+ // return color system name by bpp.
+ // for example 32 bpp means RGBA image, 1 bpp - monochrome
+ std::string colorSpaceByBpp(const s32 bpp);
+
+ void expandMono1Byte(const u32 byte, u8 *array);
+ void expandMono2Byte(const u32 byte, u8 *array);
+ void expandMono4Byte(const u32 byte, u8 *array);
+}
+
+#endif
diff --git a/kernel/include/ksquirrel-libs/settings.h b/kernel/include/ksquirrel-libs/settings.h
new file mode 100644
index 0000000..b8472c6
--- /dev/null
+++ b/kernel/include/ksquirrel-libs/settings.h
@@ -0,0 +1,69 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2007 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_LIBS_CODEC_SETTINGS_H
+#define KSQUIRREL_LIBS_CODEC_SETTINGS_H
+
+#include <map>
+#include <string>
+
+struct settings_value
+{
+ enum settings_value_type { v_bool, v_int, v_double, v_string };
+
+ settings_value()
+ : type(v_int), bVal(false), iVal(0), dVal(0.0)
+ {}
+
+ settings_value(bool _b)
+ : type(v_bool), bVal(_b)
+ {}
+
+ settings_value(int _i)
+ : type(v_int), iVal(_i)
+ {}
+
+ settings_value(double _d)
+ : type(v_double), dVal(_d)
+ {}
+
+ settings_value(const std::string &_s)
+ : type(v_string), sVal(_s)
+ {}
+
+ settings_value_type type;
+
+ // means QCheckBox
+ bool bVal;
+
+ // means KNumInput or QGroupBox
+ int iVal;
+
+ // means KDoubleNumInput
+ double dVal;
+
+ // means QLineEdit
+ std::string sVal;
+};
+
+typedef std::map<std::string, settings_value> fmt_settings;
+
+#endif
diff --git a/kernel/kls_avs/Makefile.am b/kernel/kls_avs/Makefile.am
new file mode 100644
index 0000000..0de3431
--- /dev/null
+++ b/kernel/kls_avs/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_avs.la
+
+libkls_avs_la_SOURCES = fmt_codec_avs.cpp fmt_codec_avs_defs.h
+
+libkls_avs_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_avs_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_avs/fmt_codec_avs.cpp b/kernel/kls_avs/fmt_codec_avs.cpp
new file mode 100644
index 0000000..4d93352
--- /dev/null
+++ b/kernel/kls_avs/fmt_codec_avs.cpp
@@ -0,0 +1,207 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_avs_defs.h"
+#include "fmt_codec_avs.h"
+
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "../xpm/codec_avs.xpm"
+
+/*
+ *
+ * AVS X
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.1";
+ o->name = "AVS X image";
+ o->filter = "*.x ";
+ o->mime = "";
+ o->mimetype = "image/x-avs";
+ o->config = "";
+ o->pixmap = codec_avs;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.readK(&image.w, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&image.h, sizeof(s32))) return SQE_R_BADFILE;
+
+ image.w = fmt_utils::konvertLong(image.w);
+ image.h = fmt_utils::konvertLong(image.h);
+ image.bpp = 32;
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(32);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&a, sizeof(u8))) return SQE_R_BADFILE;
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->passes = 1;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ s32 w = fmt_utils::konvertLong(writeimage.w);
+ s32 h = fmt_utils::konvertLong(writeimage.h);
+
+ if(!fws.writeK(&w, sizeof(s32))) return SQE_W_ERROR;
+ if(!fws.writeK(&h, sizeof(s32))) return SQE_W_ERROR;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ RGBA rgba;
+
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ rgba.r = scan[i].a;
+ rgba.g = scan[i].r;
+ rgba.b = scan[i].g;
+ rgba.a = scan[i].b;
+
+ if(!fws.writeK(&rgba, sizeof(RGBA))) return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("x");
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_avs/fmt_codec_avs_defs.h b/kernel/kls_avs/fmt_codec_avs_defs.h
new file mode 100644
index 0000000..3f998ba
--- /dev/null
+++ b/kernel/kls_avs/fmt_codec_avs_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_avs
+#define KSQUIRREL_CODEC_DEFS_avs
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_bmp/Makefile.am b/kernel/kls_bmp/Makefile.am
new file mode 100644
index 0000000..a53cbdf
--- /dev/null
+++ b/kernel/kls_bmp/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_bmp.la
+
+libkls_bmp_la_SOURCES = fmt_codec_bmp.cpp fmt_codec_bmp_defs.h
+
+libkls_bmp_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_bmp_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_bmp/fmt_codec_bmp.cpp b/kernel/kls_bmp/fmt_codec_bmp.cpp
new file mode 100644
index 0000000..c7be886
--- /dev/null
+++ b/kernel/kls_bmp/fmt_codec_bmp.cpp
@@ -0,0 +1,445 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_bmp_defs.h"
+#include "fmt_codec_bmp.h"
+
+#include "../xpm/codec_bmp.xpm"
+
+/*
+ *
+ * This library works with the graphics-file formats used by the Microsoft Windows(tm)
+ * operating system.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "1.1.2";
+ o->name = "Windows Bitmap";
+ o->filter = "*.bmp *.dib ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-bmp";
+ o->pixmap = codec_bmp;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ pal_entr = 0;
+ currentImage = -1;
+ read_error = false;
+
+ if(!frs.readK(&bfh, sizeof(BITMAPFILE_HEADER)))
+ return SQE_R_BADFILE;
+
+ if(!frs.readK(&bih, sizeof(BITMAPINFO_HEADER)))
+ return SQE_R_BADFILE;
+
+ if(bfh.Type != BMP_IDENTIFIER || bih.Size != 40)
+ return SQE_R_BADFILE;
+
+ if(bih.Compression != BI_RGB)
+ return SQE_R_NOTSUPPORTED;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ RGBA rgba;
+ s32 i, j, scanShouldBe;
+
+ if(bih.BitCount < 16)
+ pal_entr = 1 << bih.BitCount;
+ else
+ pal_entr = 0;
+
+ image.w = bih.Width;
+ image.h = bih.Height;
+ image.bpp = bih.BitCount;
+ scanShouldBe = bih.Width;
+
+ switch(image.bpp)
+ {
+ case 1:
+ {
+ s32 _tmp = scanShouldBe;
+ scanShouldBe /= 8;
+ scanShouldBe = scanShouldBe + ((_tmp%8)?1:0);
+ }
+ break;
+
+ case 4: scanShouldBe = ((image.w)%2)?((scanShouldBe+1)/2):(scanShouldBe/2); break;
+ case 8: break;
+ case 16: scanShouldBe *= 2; break;
+ case 24: scanShouldBe *= 3; break;
+ case 32: break;
+
+ default:
+ return SQE_R_BADFILE;
+ }
+
+ for(j = 0;j < 4;j++)
+ if((scanShouldBe+j)%4 == 0)
+ {
+ filler = j;
+ break;
+ }
+
+ if(image.bpp < 16)
+ {
+ /* read palette */
+ for(i = 0;i < pal_entr;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA)))
+ return SQE_R_BADFILE;
+
+ (pal)[i].r = rgba.b;
+ (pal)[i].g = rgba.g;
+ (pal)[i].b = rgba.r;
+ }
+ }
+
+ /* fseek to image bits */
+ frs.seekg(bfh.OffBits, ios::beg);
+
+ image.needflip = true;
+ image.colorspace = (pal_entr ? "Color indexed":"RGB");
+ image.compression = "-";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u16 remain, scanShouldBe, j, counter = 0;
+ u8 bt, dummy;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(im->bpp)
+ {
+ case 1:
+ {
+ u8 index;
+ remain=((im->w)<=8)?(0):((im->w)%8);
+ scanShouldBe = im->w;
+
+ s32 _tmp = scanShouldBe;
+ scanShouldBe /= 8;
+ scanShouldBe = scanShouldBe + ((_tmp%8)?1:0);
+
+ // @todo get rid of miltiple 'if'
+ for(j = 0;j < scanShouldBe;j++)
+ {
+ if(!frs.readK(&bt, 1))
+ return SQE_R_BADFILE;
+
+ if(j==scanShouldBe-1 && (remain-0)<=0 && remain)break; index = (bt & 128) >> 7; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-1)<=0 && remain)break; index = (bt & 64) >> 6; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-2)<=0 && remain)break; index = (bt & 32) >> 5; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-3)<=0 && remain)break; index = (bt & 16) >> 4; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-4)<=0 && remain)break; index = (bt & 8) >> 3; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-5)<=0 && remain)break; index = (bt & 4) >> 2; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-6)<=0 && remain)break; index = (bt & 2) >> 1; memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ if(j==scanShouldBe-1 && (remain-7)<=0 && remain)break; index = (bt & 1); memcpy(scan+(counter++), (pal)+index, sizeof(RGB));
+ }
+
+ for(j = 0;j < filler;j++)
+ {
+ if(!frs.readK(&dummy, 1))
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case 4:
+ {
+ u8 index;
+ remain = (im->w)%2;
+
+ s32 ck = (im->w%2)?(im->w + 1):(im->w);
+ ck /= 2;
+
+ for(j = 0;j < ck-1;j++)
+ {
+ if(!frs.readK(&bt, 1))
+ return SQE_R_BADFILE;
+
+ index = (bt & 0xf0) >> 4;
+ memcpy(scan+(counter++), (pal)+index, 3);
+ index = bt & 0xf;
+ memcpy(scan+(counter++), (pal)+index, 3);
+ }
+
+ if(!frs.readK(&bt, 1))
+ return SQE_R_BADFILE;
+
+ index = (bt & 0xf0) >> 4;
+ memcpy(scan+(counter++), (pal)+index, 3);
+
+ if(!remain)
+ {
+ index = bt & 0xf;
+ memcpy(scan+(counter++), (pal)+index, 3);
+ }
+
+ for(j = 0;j < filler;j++)
+ {
+ if(!frs.readK(&dummy, 1))
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case 8:
+ {
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&bt, 1))
+ return SQE_R_BADFILE;
+
+ memcpy(scan+(counter++), (pal)+bt, 3);
+ }
+
+ for(j = 0;j < filler;j++)
+ {
+ if(!frs.readK(&dummy, 1))
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case 16:
+ {
+ u16 word;
+
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&word, 2))
+ return SQE_R_BADFILE;
+
+ scan[counter].b = (word&0x1f) << 3;
+ scan[counter].g = ((word&0x3e0) >> 5) << 3;
+ scan[counter++].r = ((word&0x7c00)>>10) << 3;
+ }
+
+ for(j = 0;j < filler;j++)
+ {
+ if(!frs.readK(&dummy, 1))
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case 24:
+ {
+ RGB rgb;
+
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB)))
+ return SQE_R_BADFILE;
+
+ scan[counter].r = rgb.b;
+ scan[counter].g = rgb.g;
+ scan[counter].b = rgb.r;
+ counter++;
+ }
+
+ for(j = 0;j < filler;j++)
+ {
+ if(!frs.readK(&dummy, 1))
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case 32:
+ {
+ RGBA rgba;
+
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA)))
+ return SQE_R_BADFILE;
+
+ scan[j].r = rgba.b;
+ scan[j].g = rgba.g;
+ scan[j].b = rgba.r;
+ }
+ }
+ break;
+
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = true;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ m_FILLER = (image.w < 4) ? (4-image.w) : image.w%4;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ m_bfh.Type = BMP_IDENTIFIER;
+ m_bfh.Size = 0;
+ m_bfh.Reserved1 = 0;
+ m_bfh.OffBits = sizeof(BITMAPFILE_HEADER) + sizeof(BITMAPINFO_HEADER);
+
+ m_bih.Size = 40;
+ m_bih.Width = writeimage.w;
+ m_bih.Height = writeimage.h;
+ m_bih.Planes = 1;
+ m_bih.BitCount = 24;
+ m_bih.Compression = BI_RGB;
+ m_bih.SizeImage = 0;
+ m_bih.XPelsPerMeter = 0;
+ m_bih.YPelsPerMeter = 0;
+ m_bih.ClrUsed = 0;
+ m_bih.ClrImportant = 0;
+
+ if(!fws.writeK(&m_bfh, sizeof(BITMAPFILE_HEADER)))
+ return SQE_W_ERROR;
+
+ if(!fws.writeK(&m_bih, sizeof(BITMAPINFO_HEADER)))
+ return SQE_W_ERROR;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ s8 fillchar = '0';
+ RGB rgb;
+
+ for(s32 x = 0;x < writeimage.w;x++)
+ {
+ rgb.r = scan[x].b;
+ rgb.g = scan[x].g;
+ rgb.b = scan[x].r;
+
+ if(!fws.writeK(&rgb, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ if(m_FILLER)
+ {
+ for(s32 s = 0;s < m_FILLER;s++)
+ fws.writeK(&fillchar, sizeof(s8));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("bmp");
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_bmp/fmt_codec_bmp_defs.h b/kernel/kls_bmp/fmt_codec_bmp_defs.h
new file mode 100644
index 0000000..12bc3be
--- /dev/null
+++ b/kernel/kls_bmp/fmt_codec_bmp_defs.h
@@ -0,0 +1,58 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQIURREL_READ_IMAGE_bmp
+#define KSQUIRREL_READ_IMAGE_bmp
+
+/* Compression type */
+#define BI_RGB 0L
+#define BI_RLE8 1L
+#define BI_RLE4 2L
+#define BI_BITFIELDS 3L
+
+#define BMP_IDENTIFIER 0x4D42
+
+struct BITMAPFILE_HEADER
+{
+ u16 Type; /* "BM" */
+ u32 Size;
+ u32 Reserved1;
+ u32 OffBits;
+
+}PACKED;
+
+struct BITMAPINFO_HEADER
+{
+ u32 Size;
+ u32 Width;
+ u32 Height;
+ u16 Planes;
+ u16 BitCount;
+ u32 Compression;
+ u32 SizeImage;
+ u32 XPelsPerMeter;
+ u32 YPelsPerMeter;
+ u32 ClrUsed;
+ u32 ClrImportant;
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_camera/Makefile.am b/kernel/kls_camera/Makefile.am
new file mode 100644
index 0000000..275b9c4
--- /dev/null
+++ b/kernel/kls_camera/Makefile.am
@@ -0,0 +1,39 @@
+INCLUDES = -I../include
+
+# shut up gcc
+CFLAGS = -O4
+
+bin_PROGRAMS = ksquirrel-libs-dcraw
+bin_SCRIPTS = ksquirrel-libs-camera2ppm
+
+ksquirrel_libs_dcraw_SOURCES = dcraw.c
+
+if CAMERA_NO_JPEG
+camera_jpeg = -DNO_JPEG
+else
+nojpeg_opt = -ljpeg
+endif
+
+if CAMERA_NO_CMS
+camera_cms = -DNO_LCMS
+else
+nocms_opt = ${lcms_LIBS}
+endif
+
+ksquirrel_libs_dcraw_LDADD = ${nojpeg_opt} ${nocms_opt} -lm
+ksquirrel_libs_dcraw_CFLAGS = ${camera_jpeg} ${camera_cms} ${lcms_CFLAGS}
+
+pkglib_LTLIBRARIES = libkls_camera.la
+
+libkls_camera_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_camera_la_LDFLAGS = ${SQ_RELEASE}
+libkls_camera_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = ${camera_cms} -DCAMERA_UI=\"${pkgdatadir}/libkls_camera.so.ui\" -DCODEC_CAMERA -DCODEC_ANOTHER -DKLDCRAW_S=\"${bindir}/ksquirrel-libs-camera2ppm\" -DKLDCRAW=\"${bindir}/ksquirrel-libs-dcraw\"
+
+EXTRA_DIST = libkls_camera.so.ui ksquirrel-libs-camera2ppm.in
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 libkls_camera.so.ui $(DESTDIR)$(pkgdatadir)/libkls_camera.so.ui
diff --git a/kernel/kls_camera/dcraw.c b/kernel/kls_camera/dcraw.c
new file mode 100644
index 0000000..0eea8e1
--- /dev/null
+++ b/kernel/kls_camera/dcraw.c
@@ -0,0 +1,8269 @@
+/*
+ dcraw.c -- Dave Coffin's raw photo decoder
+ Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
+
+ This is a command-line ANSI C program to convert raw photos from
+ any digital camera on any computer running any operating system.
+
+ No license is required to download and use dcraw.c. However,
+ to lawfully redistribute dcraw, you must either (a) offer, at
+ no extra charge, full source code* for all executable files
+ containing RESTRICTED functions, (b) distribute this code under
+ the GPL Version 2 or later, (c) remove all RESTRICTED functions,
+ re-implement them, or copy them from an earlier, unrestricted
+ Revision of dcraw.c, or (d) purchase a license from the author.
+
+ The functions that process Foveon images have been RESTRICTED
+ since Revision 1.237. All other code remains free for all uses.
+
+ *If you have not modified dcraw.c in any way, a link to my
+ homepage qualifies as "full source code".
+
+ $Revision: 1.394 $
+ $Date: 2007/11/04 02:18:54 $
+ */
+
+#define VERSION "8.79"
+
+#define _GNU_SOURCE
+#define _USE_MATH_DEFINES
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+/*
+ NO_JPEG disables decoding of compressed Kodak DC120 files.
+ NO_LCMS disables the "-p" option.
+ */
+#ifndef NO_JPEG
+#include <jpeglib.h>
+#endif
+#ifndef NO_LCMS
+#include <lcms.h>
+#endif
+#ifdef LOCALEDIR
+#include <libintl.h>
+#define _(String) gettext(String)
+#else
+#define _(String) (String)
+#endif
+#define fgetc getc_unlocked
+#ifdef DJGPP
+#define fseeko fseek
+#define ftello ftell
+#endif
+#ifdef __CYGWIN__
+#include <io.h>
+#endif
+#ifdef WIN32
+#include <sys/utime.h>
+#include <winsock2.h>
+#pragma comment(lib, "ws2_32.lib")
+#define snprintf _snprintf
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+typedef __int64 INT64;
+typedef unsigned __int64 UINT64;
+#else
+#include <unistd.h>
+#include <utime.h>
+#include <netinet/in.h>
+typedef long long INT64;
+typedef unsigned long long UINT64;
+#endif
+
+#ifdef LJPEG_DECODE
+#error Please compile dcraw.c by itself.
+#error Do not link it with ljpeg_decode.
+#endif
+
+#ifndef LONG_BIT
+#define LONG_BIT (8 * sizeof (long))
+#endif
+
+#define ushort UshORt
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+
+/*
+ All global variables are defined here, and all functions that
+ access them are prefixed with "CLASS". Note that a thread-safe
+ C++ class cannot have non-const static local variables.
+ */
+FILE *ifp;
+short order;
+char *ifname, *meta_data;
+char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64];
+float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
+time_t timestamp;
+unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id;
+off_t strip_offset, data_offset;
+off_t thumb_offset, meta_offset, profile_offset;
+unsigned thumb_length, meta_length, profile_length;
+unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0;
+unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
+unsigned black, maximum, mix_green, raw_color, use_gamma, zero_is_bad;
+unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
+unsigned tile_width, tile_length;
+ushort raw_height, raw_width, height, width, top_margin, left_margin;
+ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
+int flip, tiff_flip, colors;
+double pixel_aspect, aber[4]={1,1,1,1};
+ushort (*image)[4], white[8][8], curve[0x4001], cr2_slice[3], sraw_mul[4];
+float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
+int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
+int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1;
+int output_color=1, output_bps=8, output_tiff=0, med_passes=0;
+unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
+float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
+const double xyz_rgb[3][3] = { /* XYZ from RGB */
+ { 0.412453, 0.357580, 0.180423 },
+ { 0.212671, 0.715160, 0.072169 },
+ { 0.019334, 0.119193, 0.950227 } };
+const float d65_white[3] = { 0.950456, 1, 1.088754 };
+int histogram[4][0x2000];
+void (*write_thumb)(FILE *), (*write_fun)(FILE *);
+void (*load_raw)(), (*thumb_load_raw)();
+jmp_buf failure;
+
+struct decode {
+ struct decode *branch[2];
+ int leaf;
+} first_decode[2048], *second_decode, *free_decode;
+
+struct {
+ int width, height, bps, comp, phint, offset, flip, samples, bytes;
+} tiff_ifd[10];
+
+struct {
+ int format, key_off, black, black_off, split_col, tag_21a;
+ float tag_210;
+} ph1;
+
+#define CLASS
+
+#define FORC3 for (c=0; c < 3; c++)
+#define FORC4 for (c=0; c < 4; c++)
+#define FORCC for (c=0; c < colors; c++)
+
+#define SQR(x) ((x)*(x))
+#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LIM(x,min,max) MAX(min,MIN(x,max))
+#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
+#define CLIP(x) LIM(x,0,65535)
+#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
+
+/*
+ In order to inline this calculation, I make the risky
+ assumption that all filter patterns can be described
+ by a repeating pattern of eight rows and two columns
+
+ Do not use the FC or BAYER macros with the Leaf CatchLight,
+ because its pattern is 16x16, not 2x8.
+
+ Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
+
+ PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
+ 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
+
+ 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
+ 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M
+ 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C
+ 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
+ 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
+ 4 C Y C Y C Y 4 Y C Y C Y C
+ PowerShot A5 5 G M G M G M 5 G M G M G M
+ 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
+ 7 M G M G M G 7 M G M G M G
+ 0 1 2 3 4 5
+ 0 C Y C Y C Y
+ 1 G M G M G M
+ 2 C Y C Y C Y
+ 3 M G M G M G
+
+ All RGB cameras use one of these Bayer grids:
+
+ 0x16161616: 0x61616161: 0x49494949: 0x94949494:
+
+ 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
+ 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G
+ 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B
+ 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G
+ 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B
+ */
+
+#define FC(row,col) \
+ (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
+
+#define BAYER(row,col) \
+ image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
+
+#define BAYER2(row,col) \
+ image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)]
+
+int CLASS fc (int row, int col)
+{
+ static const char filter[16][16] =
+ { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
+ { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
+ { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
+ { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
+ { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
+ { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
+ { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
+ { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
+ { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
+ { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
+ { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
+ { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
+ { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
+ { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
+ { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
+ { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
+
+ if (filters != 1) return FC(row,col);
+ return filter[(row+top_margin) & 15][(col+left_margin) & 15];
+}
+
+#ifndef __GLIBC__
+char *my_memmem (char *haystack, size_t haystacklen,
+ char *needle, size_t needlelen)
+{
+ char *c;
+ for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
+ if (!memcmp (c, needle, needlelen))
+ return c;
+ return 0;
+}
+#define memmem my_memmem
+#endif
+
+void CLASS merror (void *ptr, char *where)
+{
+ if (ptr) return;
+ fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
+ longjmp (failure, 1);
+}
+
+void CLASS derror()
+{
+ if (!data_error) {
+ fprintf (stderr, "%s: ", ifname);
+ if (feof(ifp))
+ fprintf (stderr,_("Unexpected end of file\n"));
+ else
+ fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
+ }
+ data_error = 1;
+}
+
+ushort CLASS sget2 (uchar *s)
+{
+ if (order == 0x4949) /* "II" means little-endian */
+ return s[0] | s[1] << 8;
+ else /* "MM" means big-endian */
+ return s[0] << 8 | s[1];
+}
+
+ushort CLASS get2()
+{
+ uchar str[2] = { 0xff,0xff };
+ fread (str, 1, 2, ifp);
+ return sget2(str);
+}
+
+unsigned CLASS sget4 (uchar *s)
+{
+ if (order == 0x4949)
+ return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
+ else
+ return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
+}
+#define sget4(s) sget4((uchar *)s)
+
+unsigned CLASS get4()
+{
+ uchar str[4] = { 0xff,0xff,0xff,0xff };
+ fread (str, 1, 4, ifp);
+ return sget4(str);
+}
+
+unsigned CLASS getint (int type)
+{
+ return type == 3 ? get2() : get4();
+}
+
+float CLASS int_to_float (int i)
+{
+ union { int i; float f; } u;
+ u.i = i;
+ return u.f;
+}
+
+double CLASS getreal (int type)
+{
+ union { char c[8]; double d; } u;
+ int i, rev;
+
+ switch (type) {
+ case 3: return (unsigned short) get2();
+ case 4: return (unsigned int) get4();
+ case 5: u.d = (unsigned int) get4();
+ return u.d / (unsigned int) get4();
+ case 8: return (signed short) get2();
+ case 9: return (signed int) get4();
+ case 10: u.d = (signed int) get4();
+ return u.d / (signed int) get4();
+ case 11: return int_to_float (get4());
+ case 12:
+ rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
+ for (i=0; i < 8; i++)
+ u.c[i ^ rev] = fgetc(ifp);
+ return u.d;
+ default: return fgetc(ifp);
+ }
+}
+#define getrat() getreal(10)
+
+void CLASS read_shorts (ushort *pixel, int count)
+{
+ if (fread (pixel, 2, count, ifp) < count) derror();
+ if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
+ swab (pixel, pixel, count*2);
+}
+
+void CLASS canon_600_fixed_wb (int temp)
+{
+ static const short mul[4][5] = {
+ { 667, 358,397,565,452 },
+ { 731, 390,367,499,517 },
+ { 1119, 396,348,448,537 },
+ { 1399, 485,431,508,688 } };
+ int lo, hi, i;
+ float frac=0;
+
+ for (lo=4; --lo; )
+ if (*mul[lo] <= temp) break;
+ for (hi=0; hi < 3; hi++)
+ if (*mul[hi] >= temp) break;
+ if (lo != hi)
+ frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
+ for (i=1; i < 5; i++)
+ pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
+}
+
+/* Return values: 0 = white 1 = near white 2 = not white */
+int CLASS canon_600_color (int ratio[2], int mar)
+{
+ int clipped=0, target, miss;
+
+ if (flash_used) {
+ if (ratio[1] < -104)
+ { ratio[1] = -104; clipped = 1; }
+ if (ratio[1] > 12)
+ { ratio[1] = 12; clipped = 1; }
+ } else {
+ if (ratio[1] < -264 || ratio[1] > 461) return 2;
+ if (ratio[1] < -50)
+ { ratio[1] = -50; clipped = 1; }
+ if (ratio[1] > 307)
+ { ratio[1] = 307; clipped = 1; }
+ }
+ target = flash_used || ratio[1] < 197
+ ? -38 - (398 * ratio[1] >> 10)
+ : -123 + (48 * ratio[1] >> 10);
+ if (target - mar <= ratio[0] &&
+ target + 20 >= ratio[0] && !clipped) return 0;
+ miss = target - ratio[0];
+ if (abs(miss) >= mar*4) return 2;
+ if (miss < -20) miss = -20;
+ if (miss > mar) miss = mar;
+ ratio[0] = target - miss;
+ return 1;
+}
+
+void CLASS canon_600_auto_wb()
+{
+ int mar, row, col, i, j, st, count[] = { 0,0 };
+ int test[8], total[2][8], ratio[2][2], stat[2];
+
+ memset (&total, 0, sizeof total);
+ i = canon_ev + 0.5;
+ if (i < 10) mar = 150;
+ else if (i > 12) mar = 20;
+ else mar = 280 - 20 * i;
+ if (flash_used) mar = 80;
+ for (row=14; row < height-14; row+=4)
+ for (col=10; col < width; col+=2) {
+ for (i=0; i < 8; i++)
+ test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
+ BAYER(row+(i >> 1),col+(i & 1));
+ for (i=0; i < 8; i++)
+ if (test[i] < 150 || test[i] > 1500) goto next;
+ for (i=0; i < 4; i++)
+ if (abs(test[i] - test[i+4]) > 50) goto next;
+ for (i=0; i < 2; i++) {
+ for (j=0; j < 4; j+=2)
+ ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
+ stat[i] = canon_600_color (ratio[i], mar);
+ }
+ if ((st = stat[0] | stat[1]) > 1) goto next;
+ for (i=0; i < 2; i++)
+ if (stat[i])
+ for (j=0; j < 2; j++)
+ test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
+ for (i=0; i < 8; i++)
+ total[st][i] += test[i];
+ count[st]++;
+next: ;
+ }
+ if (count[0] | count[1]) {
+ st = count[0]*200 < count[1];
+ for (i=0; i < 4; i++)
+ pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
+ }
+}
+
+void CLASS canon_600_coeff()
+{
+ static const short table[6][12] = {
+ { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
+ { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
+ { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
+ { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
+ { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
+ { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
+ int t=0, i, c;
+ float mc, yc;
+
+ mc = pre_mul[1] / pre_mul[2];
+ yc = pre_mul[3] / pre_mul[2];
+ if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
+ if (mc > 1.28 && mc <= 2) {
+ if (yc < 0.8789) t=3;
+ else if (yc <= 2) t=4;
+ }
+ if (flash_used) t=5;
+ for (raw_color = i=0; i < 3; i++)
+ FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
+}
+
+void CLASS canon_600_load_raw()
+{
+ uchar data[1120], *dp;
+ ushort pixel[896], *pix;
+ int irow, row, col, val;
+ static const short mul[4][2] =
+ { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
+
+ for (irow=row=0; irow < height; irow++) {
+ if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror();
+ for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) {
+ pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
+ pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
+ pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
+ pix[3] = (dp[4] << 2) + (dp[1] & 3);
+ pix[4] = (dp[5] << 2) + (dp[9] & 3);
+ pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
+ pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
+ pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
+ }
+ for (col=0; col < width; col++)
+ BAYER(row,col) = pixel[col];
+ for (col=width; col < raw_width; col++)
+ black += pixel[col];
+ if ((row+=2) > height) row = 1;
+ }
+ if (raw_width > width)
+ black = black / ((raw_width - width) * height) - 4;
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++) {
+ if ((val = BAYER(row,col) - black) < 0) val = 0;
+ val = val * mul[row & 3][col & 1] >> 9;
+ BAYER(row,col) = val;
+ }
+ canon_600_fixed_wb(1311);
+ canon_600_auto_wb();
+ canon_600_coeff();
+ maximum = (0x3ff - black) * 1109 >> 9;
+ black = 0;
+}
+
+void CLASS remove_zeroes()
+{
+ unsigned row, col, tot, n, r, c;
+
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++)
+ if (BAYER(row,col) == 0) {
+ tot = n = 0;
+ for (r = row-2; r <= row+2; r++)
+ for (c = col-2; c <= col+2; c++)
+ if (r < height && c < width &&
+ FC(r,c) == FC(row,col) && BAYER(r,c))
+ tot += (n++,BAYER(r,c));
+ if (n) BAYER(row,col) = tot/n;
+ }
+}
+
+int CLASS canon_s2is()
+{
+ unsigned row;
+
+ for (row=0; row < 100; row++) {
+ fseek (ifp, row*3340 + 3284, SEEK_SET);
+ if (getc(ifp) > 15) return 1;
+ }
+ return 0;
+}
+
+void CLASS canon_a5_load_raw()
+{
+ ushort data[2335], *dp, pixel;
+ int vbits=0, buf=0, row, col, bc=0;
+
+ order = 0x4949;
+ for (row=-top_margin; row < raw_height-top_margin; row++) {
+ read_shorts (dp=data, raw_width * 10 / 16);
+ for (col=-left_margin; col < raw_width-left_margin; col++) {
+ if (vbits < 10)
+ buf = (vbits += 16, (buf << 16) + *dp++);
+ pixel = buf >> (vbits -= 10) & 0x3ff;
+ if ((unsigned) row < height && (unsigned) col < width)
+ BAYER(row,col) = pixel;
+ else if (col > 1-left_margin && col != width)
+ black += (bc++,pixel);
+ }
+ }
+ if (bc) black /= bc;
+ maximum = 0x3ff;
+ if (raw_width > 1600) remove_zeroes();
+}
+
+/*
+ getbits(-1) initializes the buffer
+ getbits(n) where 0 <= n <= 25 returns an n-bit integer
+ */
+unsigned CLASS getbits (int nbits)
+{
+ static unsigned bitbuf=0;
+ static int vbits=0, reset=0;
+ unsigned c;
+
+ if (nbits == -1)
+ return bitbuf = vbits = reset = 0;
+ if (nbits == 0 || reset) return 0;
+ while (vbits < nbits) {
+ if ((c = fgetc(ifp)) == EOF) derror();
+ if ((reset = zero_after_ff && c == 0xff && fgetc(ifp))) return 0;
+ bitbuf = (bitbuf << 8) + (uchar) c;
+ vbits += 8;
+ }
+ vbits -= nbits;
+ return bitbuf << (32-nbits-vbits) >> (32-nbits);
+}
+
+void CLASS init_decoder()
+{
+ memset (first_decode, 0, sizeof first_decode);
+ free_decode = first_decode;
+}
+
+/*
+ Construct a decode tree according the specification in *source.
+ The first 16 bytes specify how many codes should be 1-bit, 2-bit
+ 3-bit, etc. Bytes after that are the leaf values.
+
+ For example, if the source is
+
+ { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
+ 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
+
+ then the code is
+
+ 00 0x04
+ 010 0x03
+ 011 0x05
+ 100 0x06
+ 101 0x02
+ 1100 0x07
+ 1101 0x01
+ 11100 0x08
+ 11101 0x09
+ 11110 0x00
+ 111110 0x0a
+ 1111110 0x0b
+ 1111111 0xff
+ */
+uchar * CLASS make_decoder (const uchar *source, int level)
+{
+ struct decode *cur;
+ static int leaf;
+ int i, next;
+
+ if (level==0) leaf=0;
+ cur = free_decode++;
+ if (free_decode > first_decode+2048) {
+ fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
+ longjmp (failure, 2);
+ }
+ for (i=next=0; i <= leaf && next < 16; )
+ i += source[next++];
+ if (i > leaf) {
+ if (level < next) {
+ cur->branch[0] = free_decode;
+ make_decoder (source, level+1);
+ cur->branch[1] = free_decode;
+ make_decoder (source, level+1);
+ } else
+ cur->leaf = source[16 + leaf++];
+ }
+ return (uchar *) source + 16 + leaf;
+}
+
+void CLASS crw_init_tables (unsigned table)
+{
+ static const uchar first_tree[3][29] = {
+ { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
+ 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
+ { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
+ 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
+ { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
+ 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
+ };
+ static const uchar second_tree[3][180] = {
+ { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
+ 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
+ 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
+ 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
+ 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
+ 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
+ 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
+ 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
+ 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
+ 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
+ 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
+ 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
+ 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
+ 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
+ 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
+ { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
+ 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
+ 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
+ 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
+ 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
+ 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
+ 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
+ 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
+ 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
+ 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
+ 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
+ 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
+ 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
+ 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
+ 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
+ { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
+ 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
+ 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
+ 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
+ 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
+ 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
+ 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
+ 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
+ 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
+ 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
+ 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
+ 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
+ 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
+ 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
+ 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
+ };
+ if (table > 2) table = 2;
+ init_decoder();
+ make_decoder ( first_tree[table], 0);
+ second_decode = free_decode;
+ make_decoder (second_tree[table], 0);
+}
+
+/*
+ Return 0 if the image starts with compressed data,
+ 1 if it starts with uncompressed low-order bits.
+
+ In Canon compressed data, 0xff is always followed by 0x00.
+ */
+int CLASS canon_has_lowbits()
+{
+ uchar test[0x4000];
+ int ret=1, i;
+
+ fseek (ifp, 0, SEEK_SET);
+ fread (test, 1, sizeof test, ifp);
+ for (i=540; i < sizeof test - 1; i++)
+ if (test[i] == 0xff) {
+ if (test[i+1]) return 1;
+ ret=0;
+ }
+ return ret;
+}
+
+void CLASS canon_compressed_load_raw()
+{
+ ushort *pixel, *prow;
+ int nblocks, lowbits, i, row, r, col, save, val;
+ unsigned irow, icol;
+ struct decode *decode, *dindex;
+ int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
+ uchar c;
+
+ crw_init_tables (tiff_compress);
+ pixel = (ushort *) calloc (raw_width*8, sizeof *pixel);
+ merror (pixel, "canon_compressed_load_raw()");
+ lowbits = canon_has_lowbits();
+ if (!lowbits) maximum = 0x3ff;
+ fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
+ zero_after_ff = 1;
+ getbits(-1);
+ for (row=0; row < raw_height; row+=8) {
+ nblocks = MIN (8, raw_height-row) * raw_width >> 6;
+ for (block=0; block < nblocks; block++) {
+ memset (diffbuf, 0, sizeof diffbuf);
+ decode = first_decode;
+ for (i=0; i < 64; i++ ) {
+ for (dindex=decode; dindex->branch[0]; )
+ dindex = dindex->branch[getbits(1)];
+ leaf = dindex->leaf;
+ decode = second_decode;
+ if (leaf == 0 && i) break;
+ if (leaf == 0xff) continue;
+ i += leaf >> 4;
+ len = leaf & 15;
+ if (len == 0) continue;
+ diff = getbits(len);
+ if ((diff & (1 << (len-1))) == 0)
+ diff -= (1 << len) - 1;
+ if (i < 64) diffbuf[i] = diff;
+ }
+ diffbuf[0] += carry;
+ carry = diffbuf[0];
+ for (i=0; i < 64; i++ ) {
+ if (pnum++ % raw_width == 0)
+ base[0] = base[1] = 512;
+ if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
+ derror();
+ }
+ }
+ if (lowbits) {
+ save = ftell(ifp);
+ fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
+ for (prow=pixel, i=0; i < raw_width*2; i++) {
+ c = fgetc(ifp);
+ for (r=0; r < 8; r+=2, prow++) {
+ val = (*prow << 2) + ((c >> r) & 3);
+ if (raw_width == 2672 && val < 512) val += 2;
+ *prow = val;
+ }
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+ for (r=0; r < 8; r++) {
+ irow = row - top_margin + r;
+ if (irow >= height) continue;
+ for (col=0; col < raw_width; col++) {
+ icol = col - left_margin;
+ if (icol < width)
+ BAYER(irow,icol) = pixel[r*raw_width+col];
+ else
+ black += pixel[r*raw_width+col];
+ }
+ }
+ }
+ free (pixel);
+ if (raw_width > width)
+ black /= (raw_width - width) * height;
+}
+
+/*
+ Not a full implementation of Lossless JPEG, just
+ enough to decode Canon, Kodak and Adobe DNG images.
+ */
+struct jhead {
+ int bits, high, wide, clrs, psv, restart, vpred[4];
+ struct decode *huff[4];
+ ushort *row;
+};
+
+int CLASS ljpeg_start (struct jhead *jh, int info_only)
+{
+ int i, tag, len;
+ uchar data[0x10000], *dp;
+
+ init_decoder();
+ memset (jh, 0, sizeof *jh);
+ for (i=0; i < 4; i++)
+ jh->huff[i] = free_decode;
+ jh->restart = INT_MAX;
+ fread (data, 2, 1, ifp);
+ if (data[1] != 0xd8) return 0;
+ do {
+ fread (data, 2, 2, ifp);
+ tag = data[0] << 8 | data[1];
+ len = (data[2] << 8 | data[3]) - 2;
+ if (tag <= 0xff00) return 0;
+ fread (data, 1, len, ifp);
+ switch (tag) {
+ case 0xffc0: data[7] = 0;
+ case 0xffc3:
+ jh->bits = data[0];
+ jh->high = data[1] << 8 | data[2];
+ jh->wide = data[3] << 8 | data[4];
+ jh->clrs = data[5] + (data[7] == 0x21);
+ if (len == 9 && !dng_version) getc(ifp);
+ break;
+ case 0xffc4:
+ if (info_only) break;
+ for (dp = data; dp < data+len && *dp < 4; ) {
+ jh->huff[*dp] = free_decode;
+ dp = make_decoder (++dp, 0);
+ }
+ break;
+ case 0xffda:
+ jh->psv = data[1+data[0]*2];
+ break;
+ case 0xffdd:
+ jh->restart = data[0] << 8 | data[1];
+ }
+ } while (tag != 0xffda);
+ if (info_only) return 1;
+ if (jh->clrs == 4) {
+ jh->huff[3] = jh->huff[2] = jh->huff[1];
+ jh->huff[1] = jh->huff[0];
+ }
+ jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
+ merror (jh->row, "ljpeg_start()");
+ return zero_after_ff = 1;
+}
+
+int CLASS ljpeg_diff (struct decode *dindex)
+{
+ int len, diff;
+
+ while (dindex->branch[0])
+ dindex = dindex->branch[getbits(1)];
+ len = dindex->leaf;
+ if (len == 16 && (!dng_version || dng_version >= 0x1010000))
+ return -32768;
+ diff = getbits(len);
+ if ((diff & (1 << (len-1))) == 0)
+ diff -= (1 << len) - 1;
+ return diff;
+}
+
+ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
+{
+ int col, c, diff, pred;
+ ushort mark=0, *row[3];
+
+ if (jrow * jh->wide % jh->restart == 0) {
+ FORC4 jh->vpred[c] = 1 << (jh->bits-1);
+ if (jrow)
+ do mark = (mark << 8) + (c = fgetc(ifp));
+ while (c != EOF && mark >> 4 != 0xffd);
+ getbits(-1);
+ }
+ FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
+ for (col=0; col < jh->wide; col++)
+ for (c=0; c < jh->clrs; c++) {
+ diff = ljpeg_diff (jh->huff[c]);
+ if (jh->clrs == 4 && c < 2 && (col | c))
+ pred = row[0][(c << 1)-3];
+ else if (col) pred = row[0][-jh->clrs];
+ else pred = (jh->vpred[c] += diff) - diff;
+ if (jrow && col) switch (jh->psv) {
+ case 1: break;
+ case 2: pred = row[1][0]; break;
+ case 3: pred = row[1][-jh->clrs]; break;
+ case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
+ case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
+ case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
+ case 7: pred = (pred + row[1][0]) >> 1; break;
+ default: pred = 0;
+ }
+ if ((**row = pred + diff) >> jh->bits) derror();
+ row[0]++; row[1]++;
+ }
+ return row[2];
+}
+
+void CLASS lossless_jpeg_load_raw()
+{
+ int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
+ struct jhead jh;
+ int min=INT_MAX;
+ ushort *rp;
+
+ if (!ljpeg_start (&jh, 0)) return;
+ jwide = jh.wide * jh.clrs;
+
+ for (jrow=0; jrow < jh.high; jrow++) {
+ rp = ljpeg_row (jrow, &jh);
+ for (jcol=0; jcol < jwide; jcol++) {
+ val = *rp++;
+ if (jh.bits <= 12)
+ val = curve[val];
+ if (cr2_slice[0]) {
+ jidx = jrow*jwide + jcol;
+ i = jidx / (cr2_slice[1]*jh.high);
+ if ((j = i >= cr2_slice[0]))
+ i = cr2_slice[0];
+ jidx -= i * (cr2_slice[1]*jh.high);
+ row = jidx / cr2_slice[1+j];
+ col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
+ }
+ if (raw_width == 3984 && (col -= 2) < 0)
+ col += (row--,raw_width);
+ if ((unsigned) (row-top_margin) < height) {
+ if ((unsigned) (col-left_margin) < width) {
+ BAYER(row-top_margin,col-left_margin) = val;
+ if (min > val) min = val;
+ } else black += val;
+ }
+ if (++col >= raw_width)
+ col = (row++,0);
+ }
+ }
+ free (jh.row);
+ if (raw_width > width)
+ black /= (raw_width - width) * height;
+ if (!strcasecmp(make,"KODAK"))
+ black = min;
+}
+
+void CLASS canon_sraw_load_raw()
+{
+ struct jhead jh;
+ short *rp=0, *ip;
+ int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
+
+ if (!ljpeg_start (&jh, 0)) return;
+ jwide = (jh.wide >>= 1) * 4;
+
+ for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
+ scol = ecol;
+ ecol += cr2_slice[1] >> 1;
+ if (!cr2_slice[0] || ecol > width-1) ecol = width & -2;
+ for (row=0; row < height; row++) {
+ ip = (short *) image[row*width+scol];
+ for (col=scol; col < ecol; col+=2, jcol+=4, ip+=8) {
+ if ((jcol %= jwide) == 0)
+ rp = (short *) ljpeg_row (jrow++, &jh);
+ ip[0] = rp[jcol];
+ ip[4] = rp[jcol+1];
+ ip[1] = (short) (rp[jcol+2] << 2) >> 2;
+ ip[2] = (short) (rp[jcol+3] << 2) >> 2;
+ }
+ }
+ }
+ for (row=0; row < height; row++) {
+ ip = (short *) image[row*width+1];
+ for (col=1; col < width-1; col+=2, ip+=8) {
+ ip[1] = (ip[-3] + ip[5] + 1) >> 1;
+ ip[2] = (ip[-2] + ip[6] + 1) >> 1;
+ }
+ if (col < width) { ip[1] = ip[-3]; ip[2] = ip[-2]; }
+ ip = (short *) image[row*width];
+ for (col=0; col < width; col++, ip+=4) {
+ pix[0] = ip[2] + ip[0];
+ pix[2] = ip[1] + ip[0];
+ pix[1] = ((ip[0] << 12) - ip[1]*778 - (ip[2] << 11)) >> 12;
+ FORC3 ip[c] = CLIP((pix[c] - 512) * sraw_mul[c] >> 10);
+ }
+ }
+ free (jh.row);
+ maximum = 0x3fff;
+}
+
+void CLASS adobe_copy_pixel (int row, int col, ushort **rp)
+{
+ unsigned r, c;
+
+ r = row -= top_margin;
+ c = col -= left_margin;
+ if (is_raw == 2 && shot_select) (*rp)++;
+ if (filters) {
+ if (fuji_width) {
+ r = row + fuji_width - 1 - (col >> 1);
+ c = row + ((col+1) >> 1);
+ }
+ if (r < height && c < width)
+ BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
+ *rp += is_raw;
+ } else {
+ if (r < height && c < width)
+ for (c=0; c < tiff_samples; c++)
+ image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c];
+ *rp += tiff_samples;
+ }
+ if (is_raw == 2 && shot_select) (*rp)--;
+}
+
+void CLASS adobe_dng_load_raw_lj()
+{
+ unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
+ struct jhead jh;
+ ushort *rp;
+
+ while (trow < raw_height) {
+ save = ftell(ifp);
+ if (tile_length < INT_MAX)
+ fseek (ifp, get4(), SEEK_SET);
+ if (!ljpeg_start (&jh, 0)) break;
+ jwide = jh.wide;
+ if (filters) jwide *= jh.clrs;
+ jwide /= is_raw;
+ for (row=col=jrow=0; jrow < jh.high; jrow++) {
+ rp = ljpeg_row (jrow, &jh);
+ for (jcol=0; jcol < jwide; jcol++) {
+ adobe_copy_pixel (trow+row, tcol+col, &rp);
+ if (++col >= tile_width || col >= raw_width)
+ row += 1 + (col = 0);
+ }
+ }
+ fseek (ifp, save+4, SEEK_SET);
+ if ((tcol += tile_width) >= raw_width)
+ trow += tile_length + (tcol = 0);
+ free (jh.row);
+ }
+}
+
+void CLASS adobe_dng_load_raw_nc()
+{
+ ushort *pixel, *rp;
+ int row, col;
+
+ pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);
+ merror (pixel, "adobe_dng_load_raw_nc()");
+ for (row=0; row < raw_height; row++) {
+ if (tiff_bps == 16)
+ read_shorts (pixel, raw_width * tiff_samples);
+ else {
+ getbits(-1);
+ for (col=0; col < raw_width * tiff_samples; col++)
+ pixel[col] = getbits(tiff_bps);
+ }
+ for (rp=pixel, col=0; col < raw_width; col++)
+ adobe_copy_pixel (row, col, &rp);
+ }
+ free (pixel);
+}
+
+void CLASS pentax_k10_load_raw()
+{
+ static const uchar pentax_tree[] =
+ { 0,2,3,1,1,1,1,1,1,2,0,0,0,0,0,0,
+ 3,4,2,5,1,6,0,7,8,9,10,11,12 };
+ int row, col, diff;
+ ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
+
+ init_decoder();
+ make_decoder (pentax_tree, 0);
+ getbits(-1);
+ for (row=0; row < height; row++)
+ for (col=0; col < raw_width; col++) {
+ diff = ljpeg_diff (first_decode);
+ if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+ else hpred[col & 1] += diff;
+ if (col < width)
+ BAYER(row,col) = hpred[col & 1];
+ if (hpred[col & 1] >> 12) derror();
+ }
+}
+
+void CLASS nikon_compressed_load_raw()
+{
+ static const uchar nikon_tree[][32] = {
+ { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
+ 5,4,3,6,2,7,1,0,8,9,11,10,12 },
+ { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
+ 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
+ { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
+ 5,4,6,3,7,2,8,1,9,0,10,11,12 },
+ { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
+ 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
+ { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
+ 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
+ { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
+ 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
+ struct decode *dindex;
+ ushort ver0, ver1, vpred[2][2], hpred[2], csize;
+ int i, max, step=0, huff=0, split=0, row, col, len, shl, diff;
+
+ fseek (ifp, meta_offset, SEEK_SET);
+ ver0 = fgetc(ifp);
+ ver1 = fgetc(ifp);
+ if (ver0 == 0x49 || ver1 == 0x58)
+ fseek (ifp, 2110, SEEK_CUR);
+ if (ver0 == 0x46) huff = 2;
+ if (tiff_bps == 14) huff += 3;
+ read_shorts (vpred[0], 4);
+ max = 1 << tiff_bps & 0x7fff;
+ if ((csize = get2()) > 1)
+ step = max / (csize-1);
+ if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
+ for (i=0; i < csize; i++)
+ curve[i*step] = get2();
+ for (i=0; i < max; i++)
+ curve[i] = ( curve[i-i%step]*(step-i%step) +
+ curve[i-i%step+step]*(i%step) ) / step;
+ fseek (ifp, meta_offset+562, SEEK_SET);
+ split = get2();
+ } else if (ver0 != 0x46 && csize <= 0x4001)
+ read_shorts (curve, max=csize);
+ init_decoder();
+ make_decoder (nikon_tree[huff], 0);
+ fseek (ifp, data_offset, SEEK_SET);
+ getbits(-1);
+ for (row=0; row < height; row++) {
+ if (split && row == split) {
+ init_decoder();
+ make_decoder (nikon_tree[huff+1], 0);
+ }
+ for (col=0; col < raw_width; col++) {
+ for (dindex=first_decode; dindex->branch[0]; )
+ dindex = dindex->branch[getbits(1)];
+ len = dindex->leaf & 15;
+ shl = dindex->leaf >> 4;
+ diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
+ if ((diff & (1 << (len-1))) == 0)
+ diff -= (1 << len) - !shl;
+ if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+ else hpred[col & 1] += diff;
+ if (hpred[col & 1] >= max) derror();
+ if ((unsigned) (col-left_margin) < width)
+ BAYER(row,col-left_margin) = curve[hpred[col & 1] & 0x3fff];
+ }
+ }
+}
+
+void CLASS nikon_load_raw()
+{
+ int irow, row, col, i;
+
+ getbits(-1);
+ for (irow=0; irow < height; irow++) {
+ row = irow;
+ if (make[0] == 'O' || model[0] == 'E') {
+ row = irow * 2 % height + irow / (height/2);
+ if (row == 1 && data_offset == 0) {
+ fseek (ifp, 0, SEEK_END);
+ fseek (ifp, ftell(ifp)/2, SEEK_SET);
+ getbits(-1);
+ }
+ }
+ for (col=0; col < raw_width; col++) {
+ i = getbits(12);
+ if ((unsigned) (col-left_margin) < width)
+ BAYER(row,col-left_margin) = i;
+ if (tiff_compress > 32768 && (col % 10) == 9)
+ if (getbits(8)) derror();
+ }
+ }
+}
+
+/*
+ Figure out if a NEF file is compressed. These fancy heuristics
+ are only needed for the D100, thanks to a bug in some cameras
+ that tags all images as "compressed".
+ */
+int CLASS nikon_is_compressed()
+{
+ uchar test[256];
+ int i;
+
+ fseek (ifp, data_offset, SEEK_SET);
+ fread (test, 1, 256, ifp);
+ for (i=15; i < 256; i+=16)
+ if (test[i]) return 1;
+ return 0;
+}
+
+/*
+ Returns 1 for a Coolpix 995, 0 for anything else.
+ */
+int CLASS nikon_e995()
+{
+ int i, histo[256];
+ const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
+
+ memset (histo, 0, sizeof histo);
+ fseek (ifp, -2000, SEEK_END);
+ for (i=0; i < 2000; i++)
+ histo[fgetc(ifp)]++;
+ for (i=0; i < 4; i++)
+ if (histo[often[i]] < 200)
+ return 0;
+ return 1;
+}
+
+/*
+ Returns 1 for a Coolpix 2100, 0 for anything else.
+ */
+int CLASS nikon_e2100()
+{
+ uchar t[12];
+ int i;
+
+ fseek (ifp, 0, SEEK_SET);
+ for (i=0; i < 1024; i++) {
+ fread (t, 1, 12, ifp);
+ if (((t[2] & t[4] & t[7] & t[9]) >> 4
+ & t[1] & t[6] & t[8] & t[11] & 3) != 3)
+ return 0;
+ }
+ return 1;
+}
+
+void CLASS nikon_3700()
+{
+ int bits, i;
+ uchar dp[24];
+ static const struct {
+ int bits;
+ char make[12], model[15];
+ } table[] = {
+ { 0x00, "PENTAX", "Optio 33WR" },
+ { 0x03, "NIKON", "E3200" },
+ { 0x32, "NIKON", "E3700" },
+ { 0x33, "OLYMPUS", "C740UZ" } };
+
+ fseek (ifp, 3072, SEEK_SET);
+ fread (dp, 1, 24, ifp);
+ bits = (dp[8] & 3) << 4 | (dp[20] & 3);
+ for (i=0; i < sizeof table / sizeof *table; i++)
+ if (bits == table[i].bits) {
+ strcpy (make, table[i].make );
+ strcpy (model, table[i].model);
+ }
+}
+
+/*
+ Separates a Minolta DiMAGE Z2 from a Nikon E4300.
+ */
+int CLASS minolta_z2()
+{
+ int i;
+ char tail[424];
+
+ fseek (ifp, -sizeof tail, SEEK_END);
+ fread (tail, 1, sizeof tail, ifp);
+ for (i=0; i < sizeof tail; i++)
+ if (tail[i]) return 1;
+ return 0;
+}
+
+/* Here raw_width is in bytes, not pixels. */
+void CLASS nikon_e900_load_raw()
+{
+ int offset=0, irow, row, col;
+
+ for (irow=0; irow < height; irow++) {
+ row = irow * 2 % height;
+ if (row == 1)
+ offset = - (-offset & -4096);
+ fseek (ifp, offset, SEEK_SET);
+ offset += raw_width;
+ getbits(-1);
+ for (col=0; col < width; col++)
+ BAYER(row,col) = getbits(10);
+ }
+}
+
+void CLASS nikon_e2100_load_raw()
+{
+ uchar data[4608], *dp;
+ ushort pixel[3072], *pix;
+ int row, col;
+
+ for (row=0; row <= height; row+=2) {
+ if (row == height) {
+ fseek (ifp, 0, SEEK_END);
+ fseek (ifp, ftell(ifp)/2, SEEK_SET);
+ row = 1;
+ }
+ fread (data, 1, width*3/2, ifp);
+ for (dp=data, pix=pixel; pix < pixel+width; dp+=12, pix+=8) {
+ pix[0] = (dp[2] >> 4) + (dp[ 3] << 4);
+ pix[1] = (dp[2] << 8) + dp[ 1];
+ pix[2] = (dp[7] >> 4) + (dp[ 0] << 4);
+ pix[3] = (dp[7] << 8) + dp[ 6];
+ pix[4] = (dp[4] >> 4) + (dp[ 5] << 4);
+ pix[5] = (dp[4] << 8) + dp[11];
+ pix[6] = (dp[9] >> 4) + (dp[10] << 4);
+ pix[7] = (dp[9] << 8) + dp[ 8];
+ }
+ for (col=0; col < width; col++)
+ BAYER(row,col) = (pixel[col] & 0xfff);
+ }
+}
+
+/*
+ The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
+ */
+void CLASS fuji_load_raw()
+{
+ ushort *pixel;
+ int wide, row, col, r, c;
+
+ fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
+ wide = fuji_width << !fuji_layout;
+ pixel = (ushort *) calloc (wide, sizeof *pixel);
+ merror (pixel, "fuji_load_raw()");
+ for (row=0; row < raw_height; row++) {
+ read_shorts (pixel, wide);
+ fseek (ifp, 2*(raw_width - wide), SEEK_CUR);
+ for (col=0; col < wide; col++) {
+ if (fuji_layout) {
+ r = fuji_width - 1 - col + (row >> 1);
+ c = col + ((row+1) >> 1);
+ } else {
+ r = fuji_width - 1 + row - (col >> 1);
+ c = row + ((col+1) >> 1);
+ }
+ BAYER(r,c) = pixel[col];
+ }
+ }
+ free (pixel);
+}
+
+void CLASS jpeg_thumb (FILE *tfp);
+
+void CLASS ppm_thumb (FILE *tfp)
+{
+ char *thumb;
+ thumb_length = thumb_width*thumb_height*3;
+ thumb = (char *) malloc (thumb_length);
+ merror (thumb, "ppm_thumb()");
+ fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
+ fread (thumb, 1, thumb_length, ifp);
+ fwrite (thumb, 1, thumb_length, tfp);
+ free (thumb);
+}
+
+void CLASS layer_thumb (FILE *tfp)
+{
+ int i, c;
+ char *thumb, map[][4] = { "012","102" };
+
+ colors = thumb_misc >> 5 & 7;
+ thumb_length = thumb_width*thumb_height;
+ thumb = (char *) calloc (colors, thumb_length);
+ merror (thumb, "layer_thumb()");
+ fprintf (tfp, "P%d\n%d %d\n255\n",
+ 5 + (colors >> 1), thumb_width, thumb_height);
+ fread (thumb, thumb_length, colors, ifp);
+ for (i=0; i < thumb_length; i++)
+ FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], tfp);
+ free (thumb);
+}
+
+void CLASS rollei_thumb (FILE *tfp)
+{
+ unsigned i;
+ ushort *thumb;
+
+ thumb_length = thumb_width * thumb_height;
+ thumb = (ushort *) calloc (thumb_length, 2);
+ merror (thumb, "rollei_thumb()");
+ fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
+ read_shorts (thumb, thumb_length);
+ for (i=0; i < thumb_length; i++) {
+ putc (thumb[i] << 3, tfp);
+ putc (thumb[i] >> 5 << 2, tfp);
+ putc (thumb[i] >> 11 << 3, tfp);
+ }
+ free (thumb);
+}
+
+void CLASS rollei_load_raw()
+{
+ uchar pixel[10];
+ unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
+
+ isix = raw_width * raw_height * 5 / 8;
+ while (fread (pixel, 1, 10, ifp) == 10) {
+ for (i=0; i < 10; i+=2) {
+ todo[i] = iten++;
+ todo[i+1] = pixel[i] << 8 | pixel[i+1];
+ buffer = pixel[i] >> 2 | buffer << 6;
+ }
+ for ( ; i < 16; i+=2) {
+ todo[i] = isix++;
+ todo[i+1] = buffer >> (14-i)*5;
+ }
+ for (i=0; i < 16; i+=2) {
+ row = todo[i] / raw_width - top_margin;
+ col = todo[i] % raw_width - left_margin;
+ if (row < height && col < width)
+ BAYER(row,col) = (todo[i+1] & 0x3ff);
+ }
+ }
+ maximum = 0x3ff;
+}
+
+int CLASS bayer (unsigned row, unsigned col)
+{
+ return (row < height && col < width) ? BAYER(row,col) : 0;
+}
+
+void CLASS phase_one_flat_field (int is_float, int nc)
+{
+ ushort head[8];
+ unsigned wide, y, x, c, rend, cend, row, col;
+ float *mrow, num, mult[4];
+
+ read_shorts (head, 8);
+ wide = head[2] / head[4];
+ mrow = (float *) calloc (nc*wide, sizeof *mrow);
+ merror (mrow, "phase_one_flat_field()");
+ for (y=0; y < head[3] / head[5]; y++) {
+ for (x=0; x < wide; x++)
+ for (c=0; c < nc; c+=2) {
+ num = is_float ? getreal(11) : get2()/32768.0;
+ if (y==0) mrow[c*wide+x] = num;
+ else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
+ }
+ if (y==0) continue;
+ rend = head[1]-top_margin + y*head[5];
+ for (row = rend-head[5]; row < height && row < rend; row++) {
+ for (x=1; x < wide; x++) {
+ for (c=0; c < nc; c+=2) {
+ mult[c] = mrow[c*wide+x-1];
+ mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
+ }
+ cend = head[0]-left_margin + x*head[4];
+ for (col = cend-head[4]; col < width && col < cend; col++) {
+ c = nc > 2 ? FC(row,col) : 0;
+ if (!(c & 1)) {
+ c = BAYER(row,col) * mult[c];
+ BAYER(row,col) = LIM(c,0,65535);
+ }
+ for (c=0; c < nc; c+=2)
+ mult[c] += mult[c+1];
+ }
+ }
+ for (x=0; x < wide; x++)
+ for (c=0; c < nc; c+=2)
+ mrow[c*wide+x] += mrow[(c+1)*wide+x];
+ }
+ }
+ free (mrow);
+}
+
+void CLASS phase_one_correct()
+{
+ unsigned entries, tag, data, save, col, row, type;
+ int len, i, j, k, cip, val[4], dev[4], sum, max;
+ int head[9], diff, mindiff=INT_MAX, off_412=0;
+ static const signed char dir[12][2] =
+ { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
+ {-2,-2}, {-2,2}, {2,-2}, {2,2} };
+ float poly[8], num, cfrac, frac, mult[2], *yval[2];
+ ushort curve[0x10000], *xval[2];
+
+ if (half_size || !meta_length) return;
+ if (verbose) fprintf (stderr,_("Phase One correction...\n"));
+ fseek (ifp, meta_offset, SEEK_SET);
+ order = get2();
+ fseek (ifp, 6, SEEK_CUR);
+ fseek (ifp, meta_offset+get4(), SEEK_SET);
+ entries = get4(); get4();
+ while (entries--) {
+ tag = get4();
+ len = get4();
+ data = get4();
+ save = ftell(ifp);
+ fseek (ifp, meta_offset+data, SEEK_SET);
+ if (tag == 0x419) { /* Polynomial curve */
+ for (get4(), i=0; i < 8; i++)
+ poly[i] = getreal(11);
+ poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
+ for (i=0; i < 0x10000; i++) {
+ num = (poly[5]*i + poly[3])*i + poly[1];
+ curve[i] = LIM(num,0,65535);
+ } goto apply; /* apply to right half */
+ } else if (tag == 0x41a) { /* Polynomial curve */
+ for (i=0; i < 4; i++)
+ poly[i] = getreal(11);
+ for (i=0; i < 0x10000; i++) {
+ for (num=0, j=4; j--; )
+ num = num * i + poly[j];
+ curve[i] = LIM(num+i,0,65535);
+ } apply: /* apply to whole image */
+ for (row=0; row < height; row++)
+ for (col = (tag & 1)*ph1.split_col; col < width; col++)
+ BAYER(row,col) = curve[BAYER(row,col)];
+ } else if (tag == 0x400) { /* Sensor defects */
+ while ((len -= 8) >= 0) {
+ col = get2() - left_margin;
+ row = get2() - top_margin;
+ type = get2(); get2();
+ if (col >= width) continue;
+ if (type == 131) /* Bad column */
+ for (row=0; row < height; row++)
+ if (FC(row,col) == 1) {
+ for (sum=i=0; i < 4; i++)
+ sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]);
+ for (max=i=0; i < 4; i++) {
+ dev[i] = abs((val[i] << 2) - sum);
+ if (dev[max] < dev[i]) max = i;
+ }
+ BAYER(row,col) = (sum - val[max])/3.0 + 0.5;
+ } else {
+ for (sum=0, i=8; i < 12; i++)
+ sum += bayer (row+dir[i][0], col+dir[i][1]);
+ BAYER(row,col) = 0.5 + sum * 0.0732233 +
+ (bayer(row,col-2) + bayer(row,col+2)) * 0.3535534;
+ }
+ else if (type == 129) { /* Bad pixel */
+ if (row >= height) continue;
+ j = (FC(row,col) != 1) * 4;
+ for (sum=0, i=j; i < j+8; i++)
+ sum += bayer (row+dir[i][0], col+dir[i][1]);
+ BAYER(row,col) = (sum + 4) >> 3;
+ }
+ }
+ } else if (tag == 0x401) { /* All-color flat fields */
+ phase_one_flat_field (1, 2);
+ } else if (tag == 0x416 || tag == 0x410) {
+ phase_one_flat_field (0, 2);
+ } else if (tag == 0x40b) { /* Red+blue flat field */
+ phase_one_flat_field (0, 4);
+ } else if (tag == 0x412) {
+ fseek (ifp, 36, SEEK_CUR);
+ diff = abs (get2() - ph1.tag_21a);
+ if (mindiff > diff) {
+ mindiff = diff;
+ off_412 = ftell(ifp) - 38;
+ }
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+ if (off_412) {
+ fseek (ifp, off_412, SEEK_SET);
+ for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
+ yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
+ merror (yval[0], "phase_one_correct()");
+ yval[1] = (float *) (yval[0] + head[1]*head[3]);
+ xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
+ xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
+ get2();
+ for (i=0; i < 2; i++)
+ for (j=0; j < head[i+1]*head[i+3]; j++)
+ yval[i][j] = getreal(11);
+ for (i=0; i < 2; i++)
+ for (j=0; j < head[i+1]*head[i+3]; j++)
+ xval[i][j] = get2();
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++) {
+ cfrac = (float) col * head[3] / raw_width;
+ cfrac -= cip = cfrac;
+ num = BAYER(row,col) * 0.5;
+ for (i=cip; i < cip+2; i++) {
+ for (k=j=0; j < head[1]; j++)
+ if (num < xval[0][k = head[1]*i+j]) break;
+ frac = (j == 0 || j == head[1]) ? 0 :
+ (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
+ mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
+ }
+ i = ((mult[0] * (1-cfrac) + mult[1] * cfrac)
+ * (row + top_margin) + num) * 2;
+ BAYER(row,col) = LIM(i,0,65535);
+ }
+ free (yval[0]);
+ }
+}
+
+void CLASS phase_one_load_raw()
+{
+ int row, col, a, b;
+ ushort *pixel, akey, bkey, mask;
+
+ fseek (ifp, ph1.key_off, SEEK_SET);
+ akey = get2();
+ bkey = get2();
+ mask = ph1.format == 1 ? 0x5555:0x1354;
+ fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET);
+ pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+ merror (pixel, "phase_one_load_raw()");
+ for (row=0; row < height; row++) {
+ read_shorts (pixel, raw_width);
+ for (col=0; col < raw_width; col+=2) {
+ a = pixel[col+0] ^ akey;
+ b = pixel[col+1] ^ bkey;
+ pixel[col+0] = (a & mask) | (b & ~mask);
+ pixel[col+1] = (b & mask) | (a & ~mask);
+ }
+ for (col=0; col < width; col++)
+ BAYER(row,col) = pixel[col+left_margin];
+ }
+ free (pixel);
+ phase_one_correct();
+}
+
+unsigned CLASS ph1_bits (int nbits)
+{
+ static UINT64 bitbuf=0;
+ static int vbits=0;
+
+ if (nbits == -1)
+ return bitbuf = vbits = 0;
+ if (nbits == 0) return 0;
+ if (vbits < nbits) {
+ bitbuf = bitbuf << 32 | get4();
+ vbits += 32;
+ }
+ vbits -= nbits;
+ return bitbuf << (64-nbits-vbits) >> (64-nbits);
+}
+
+void CLASS phase_one_load_raw_c()
+{
+ static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
+ int *offset, len[2], pred[2], row, col, i, j;
+ ushort *pixel;
+ short (*black)[2];
+
+ pixel = (ushort *) calloc (raw_width + raw_height*4, 2);
+ merror (pixel, "phase_one_load_raw_c()");
+ offset = (int *) (pixel + raw_width);
+ fseek (ifp, strip_offset, SEEK_SET);
+ for (row=0; row < raw_height; row++)
+ offset[row] = get4();
+ black = (short (*)[2]) offset + raw_height;
+ fseek (ifp, ph1.black_off, SEEK_SET);
+ if (ph1.black_off)
+ read_shorts ((ushort *) black[0], raw_height*2);
+ for (i=0; i < 256; i++)
+ curve[i] = i*i / 3.969 + 0.5;
+ for (row=0; row < raw_height; row++) {
+ fseek (ifp, data_offset + offset[row], SEEK_SET);
+ ph1_bits(-1);
+ pred[0] = pred[1] = 0;
+ for (col=0; col < raw_width; col++) {
+ if (col >= (raw_width & -8))
+ len[0] = len[1] = 14;
+ else if ((col & 7) == 0)
+ for (i=0; i < 2; i++) {
+ for (j=0; j < 5 && !ph1_bits(1); j++);
+ if (j--) len[i] = length[j*2 + ph1_bits(1)];
+ }
+ if ((i = len[col & 1]) == 14)
+ pixel[col] = pred[col & 1] = ph1_bits(16);
+ else
+ pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
+ if (pred[col & 1] >> 16) derror();
+ if (ph1.format == 5 && pixel[col] < 256)
+ pixel[col] = curve[pixel[col]];
+ }
+ if ((unsigned) (row-top_margin) < height)
+ for (col=0; col < width; col++) {
+ i = (pixel[col+left_margin] << 2)
+ - ph1.black + black[row][col >= ph1.split_col];
+ if (i > 0) BAYER(row-top_margin,col) = i;
+ }
+ }
+ free (pixel);
+ phase_one_correct();
+ maximum = 0xfffc - ph1.black;
+}
+
+void CLASS hasselblad_load_raw()
+{
+ struct jhead jh;
+ struct decode *dindex;
+ int row, col, pred[2], len[2], diff, i;
+
+ if (!ljpeg_start (&jh, 0)) return;
+ free (jh.row);
+ ph1_bits(-1);
+ for (row=0; row < height; row++) {
+ pred[0] = pred[1] = 0x8000;
+ for (col=0; col < width; col+=2) {
+ for (i=0; i < 2; i++) {
+ for (dindex=jh.huff[0]; dindex->branch[0]; )
+ dindex = dindex->branch[ph1_bits(1)];
+ len[i] = dindex->leaf;
+ }
+ for (i=0; i < 2; i++) {
+ diff = ph1_bits(len[i]);
+ if ((diff & (1 << (len[i]-1))) == 0)
+ diff -= (1 << len[i]) - 1;
+ BAYER(row,col+i) = pred[i] += diff;
+ }
+ }
+ }
+ maximum = 0xffff;
+}
+
+void CLASS leaf_hdr_load_raw()
+{
+ ushort *pixel;
+ unsigned tile=0, r, c, row, col;
+
+ pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+ merror (pixel, "leaf_hdr_load_raw()");
+ for (c=0; c < tiff_samples; c++) {
+ for (r=0; r < raw_height; r++) {
+ if (r % tile_length == 0) {
+ fseek (ifp, data_offset + 4*tile++, SEEK_SET);
+ fseek (ifp, get4() + 2*left_margin, SEEK_SET);
+ }
+ if (filters && c != shot_select) continue;
+ read_shorts (pixel, raw_width);
+ if ((row = r - top_margin) >= height) continue;
+ for (col=0; col < width; col++)
+ if (filters) BAYER(row,col) = pixel[col];
+ else image[row*width+col][c] = pixel[col];
+ }
+ }
+ free (pixel);
+ if (!filters) {
+ maximum = 0xffff;
+ raw_color = 1;
+ }
+}
+
+void CLASS unpacked_load_raw();
+
+void CLASS sinar_4shot_load_raw()
+{
+ ushort *pixel;
+ unsigned shot, row, col, r, c;
+
+ if ((shot = shot_select) || half_size) {
+ if (shot) shot--;
+ if (shot > 3) shot = 3;
+ fseek (ifp, data_offset + shot*4, SEEK_SET);
+ fseek (ifp, get4(), SEEK_SET);
+ unpacked_load_raw();
+ return;
+ }
+ free (image);
+ image = (ushort (*)[4])
+ calloc ((iheight=height)*(iwidth=width), sizeof *image);
+ merror (image, "sinar_4shot_load_raw()");
+ pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+ merror (pixel, "sinar_4shot_load_raw()");
+ for (shot=0; shot < 4; shot++) {
+ fseek (ifp, data_offset + shot*4, SEEK_SET);
+ fseek (ifp, get4(), SEEK_SET);
+ for (row=0; row < raw_height; row++) {
+ read_shorts (pixel, raw_width);
+ if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
+ for (col=0; col < raw_width; col++) {
+ if ((c = col-left_margin - (shot & 1)) >= width) continue;
+ image[r*width+c][FC(row,col)] = pixel[col];
+ }
+ }
+ }
+ free (pixel);
+ shrink = filters = 0;
+}
+
+void CLASS imacon_full_load_raw()
+{
+ int row, col;
+
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++)
+ read_shorts (image[row*width+col], 3);
+}
+
+void CLASS packed_12_load_raw()
+{
+ int row, col;
+
+ if (raw_width * 2 < width * 3)
+ raw_width = raw_width * 3 / 2; /* Convert raw_width to bytes */
+ getbits(-1);
+ for (row=0; row < height; row++) {
+ for (col=0; col < left_margin; col++)
+ getbits(12);
+ for (col=0; col < width; col++)
+ BAYER(row,col) = getbits(12);
+ for (col = (width+left_margin)*3/2; col < raw_width; col++)
+ if (getbits(8) && raw_width-col < 35 && width != 3896) derror();
+ }
+}
+
+void CLASS unpacked_load_raw()
+{
+ ushort *pixel;
+ int row, col, bits=0;
+
+ while (1 << ++bits < maximum);
+ fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
+ pixel = (ushort *) calloc (width, sizeof *pixel);
+ merror (pixel, "unpacked_load_raw()");
+ for (row=0; row < height; row++) {
+ read_shorts (pixel, width);
+ fseek (ifp, 2*(raw_width - width), SEEK_CUR);
+ for (col=0; col < width; col++)
+ if ((BAYER2(row,col) = pixel[col]) >> bits) derror();
+ }
+ free (pixel);
+}
+
+void CLASS olympus_e300_load_raw()
+{
+ uchar *data, *dp;
+ ushort *pixel, *pix;
+ int dwide, row, col;
+
+ dwide = raw_width * 16 / 10;
+ fseek (ifp, dwide*top_margin, SEEK_CUR);
+ data = (uchar *) malloc (dwide + raw_width*2);
+ merror (data, "olympus_e300_load_raw()");
+ pixel = (ushort *) (data + dwide);
+ for (row=0; row < height; row++) {
+ if (fread (data, 1, dwide, ifp) < dwide) derror();
+ for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=3, pix+=2) {
+ if (((dp-data) & 15) == 15)
+ if (*dp++ && pix < pixel+width+left_margin) derror();
+ pix[0] = dp[1] << 8 | dp[0];
+ pix[1] = dp[2] << 4 | dp[1] >> 4;
+ }
+ for (col=0; col < width; col++)
+ BAYER(row,col) = (pixel[col+left_margin] & 0xfff);
+ }
+ free (data);
+ maximum >>= 4;
+ black >>= 4;
+}
+
+void CLASS olympus_e410_load_raw()
+{
+ int row, col, nbits, sign, low, high, i, w, n, nw;
+ int acarry[2][3], *carry, pred, diff;
+
+ fseek (ifp, 7, SEEK_CUR);
+ getbits(-1);
+ for (row=0; row < height; row++) {
+ memset (acarry, 0, sizeof acarry);
+ for (col=0; col < width; col++) {
+ carry = acarry[col & 1];
+ i = 2 * (carry[2] < 3);
+ for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
+ sign = getbits(1) * -1;
+ low = getbits(2);
+ for (high=0; high < 12; high++)
+ if (getbits(1)) break;
+ if (high == 12)
+ high = getbits(16-nbits) >> 1;
+ carry[0] = (high << nbits) | getbits(nbits);
+ diff = (carry[0] ^ sign) + carry[1];
+ carry[1] = (diff*3 + carry[1]) >> 5;
+ carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
+ if (row < 2 && col < 2) pred = 0;
+ else if (row < 2) pred = BAYER(row,col-2);
+ else if (col < 2) pred = BAYER(row-2,col);
+ else {
+ w = BAYER(row,col-2);
+ n = BAYER(row-2,col);
+ nw = BAYER(row-2,col-2);
+ if ((w < nw && nw < n) || (n < nw && nw < w)) {
+ if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
+ pred = w + n - nw;
+ else pred = (w + n) >> 1;
+ } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
+ }
+ if ((BAYER(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
+ }
+ }
+}
+
+void CLASS olympus_cseries_load_raw()
+{
+ int irow, row, col;
+
+ for (irow=0; irow < height; irow++) {
+ row = irow * 2 % height + irow / (height/2);
+ if (row < 2) {
+ fseek (ifp, data_offset - row*(-width*height*3/4 & -2048), SEEK_SET);
+ getbits(-1);
+ }
+ for (col=0; col < width; col++)
+ BAYER(row,col) = getbits(12);
+ }
+ black >>= 4;
+}
+
+void CLASS minolta_rd175_load_raw()
+{
+ uchar pixel[768];
+ unsigned irow, box, row, col;
+
+ for (irow=0; irow < 1481; irow++) {
+ if (fread (pixel, 1, 768, ifp) < 768) derror();
+ box = irow / 82;
+ row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
+ switch (irow) {
+ case 1477: case 1479: continue;
+ case 1476: row = 984; break;
+ case 1480: row = 985; break;
+ case 1478: row = 985; box = 1;
+ }
+ if ((box < 12) && (box & 1)) {
+ for (col=0; col < 1533; col++, row ^= 1)
+ if (col != 1) BAYER(row,col) = (col+1) & 2 ?
+ pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
+ BAYER(row,1) = pixel[1] << 1;
+ BAYER(row,1533) = pixel[765] << 1;
+ } else
+ for (col=row & 1; col < 1534; col+=2)
+ BAYER(row,col) = pixel[col/2] << 1;
+ }
+ maximum = 0xff << 1;
+}
+
+void CLASS casio_qv5700_load_raw()
+{
+ uchar data[3232], *dp;
+ ushort pixel[2576], *pix;
+ int row, col;
+
+ for (row=0; row < height; row++) {
+ fread (data, 1, 3232, ifp);
+ for (dp=data, pix=pixel; dp < data+3220; dp+=5, pix+=4) {
+ pix[0] = (dp[0] << 2) + (dp[1] >> 6);
+ pix[1] = (dp[1] << 4) + (dp[2] >> 4);
+ pix[2] = (dp[2] << 6) + (dp[3] >> 2);
+ pix[3] = (dp[3] << 8) + (dp[4] );
+ }
+ for (col=0; col < width; col++)
+ BAYER(row,col) = (pixel[col] & 0x3ff);
+ }
+ maximum = 0x3fc;
+}
+
+void CLASS quicktake_100_load_raw()
+{
+ uchar pixel[484][644];
+ static const short gstep[16] =
+ { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
+ static const short rstep[6][4] =
+ { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
+ { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
+ static const short curve[256] =
+ { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
+ 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
+ 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
+ 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
+ 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
+ 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
+ 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
+ 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
+ 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
+ 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
+ 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
+ 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
+ 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
+ int rb, row, col, sharp, val=0;
+
+ getbits(-1);
+ memset (pixel, 0x80, sizeof pixel);
+ for (row=2; row < height+2; row++) {
+ for (col=2+(row & 1); col < width+2; col+=2) {
+ val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
+ pixel[row][col-2]) >> 2) + gstep[getbits(4)];
+ pixel[row][col] = val = LIM(val,0,255);
+ if (col < 4)
+ pixel[row][col-2] = pixel[row+1][~row & 1] = val;
+ if (row == 2)
+ pixel[row-1][col+1] = pixel[row-1][col+3] = val;
+ }
+ pixel[row][col] = val;
+ }
+ for (rb=0; rb < 2; rb++)
+ for (row=2+rb; row < height+2; row+=2)
+ for (col=3-(row & 1); col < width+2; col+=2) {
+ if (row < 4 || col < 4) sharp = 2;
+ else {
+ val = ABS(pixel[row-2][col] - pixel[row][col-2])
+ + ABS(pixel[row-2][col] - pixel[row-2][col-2])
+ + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
+ sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
+ val < 32 ? 3 : val < 48 ? 4 : 5;
+ }
+ val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
+ + rstep[sharp][getbits(2)];
+ pixel[row][col] = val = LIM(val,0,255);
+ if (row < 4) pixel[row-2][col+2] = val;
+ if (col < 4) pixel[row+2][col-2] = val;
+ }
+ for (row=2; row < height+2; row++)
+ for (col=3-(row & 1); col < width+2; col+=2) {
+ val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
+ pixel[row][col+1]) >> 1) - 0x100;
+ pixel[row][col] = LIM(val,0,255);
+ }
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++)
+ BAYER(row,col) = curve[pixel[row+2][col+2]];
+ maximum = 0x3ff;
+}
+
+const int * CLASS make_decoder_int (const int *source, int level)
+{
+ struct decode *cur;
+
+ cur = free_decode++;
+ if (level < source[0]) {
+ cur->branch[0] = free_decode;
+ source = make_decoder_int (source, level+1);
+ cur->branch[1] = free_decode;
+ source = make_decoder_int (source, level+1);
+ } else {
+ cur->leaf = source[1];
+ source += 2;
+ }
+ return source;
+}
+
+int CLASS radc_token (int tree)
+{
+ int t;
+ static struct decode *dstart[18], *dindex;
+ static const int *s, source[] = {
+ 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
+ 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
+ 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
+ 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
+ 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
+ 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
+ 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
+ 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
+ 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
+ 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
+ 1,0, 2,2, 2,-2,
+ 1,-3, 1,3,
+ 2,-17, 2,-5, 2,5, 2,17,
+ 2,-7, 2,2, 2,9, 2,18,
+ 2,-18, 2,-9, 2,-2, 2,7,
+ 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
+ 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
+ 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
+ };
+
+ if (free_decode == first_decode)
+ for (s=source, t=0; t < 18; t++) {
+ dstart[t] = free_decode;
+ s = make_decoder_int (s, 0);
+ }
+ if (tree == 18) {
+ if (kodak_cbpp == 243)
+ return (getbits(6) << 2) + 2; /* most DC50 photos */
+ else
+ return (getbits(5) << 3) + 4; /* DC40, Fotoman Pixtura */
+ }
+ for (dindex = dstart[tree]; dindex->branch[0]; )
+ dindex = dindex->branch[getbits(1)];
+ return dindex->leaf;
+}
+
+#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
+
+#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
+: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
+
+void CLASS kodak_radc_load_raw()
+{
+ int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
+ short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
+
+ init_decoder();
+ getbits(-1);
+ for (i=0; i < sizeof(buf)/sizeof(short); i++)
+ buf[0][0][i] = 2048;
+ for (row=0; row < height; row+=4) {
+ FORC3 mul[c] = getbits(6);
+ FORC3 {
+ val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
+ s = val > 65564 ? 10:12;
+ x = ~(-1 << (s-1));
+ val <<= 12-s;
+ for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
+ buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
+ last[c] = mul[c];
+ for (r=0; r <= !c; r++) {
+ buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
+ for (tree=1, col=width/2; col > 0; ) {
+ if ((tree = radc_token(tree))) {
+ col -= 2;
+ if (tree == 8)
+ FORYX buf[c][y][x] = radc_token(tree+10) * mul[c];
+ else
+ FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
+ } else
+ do {
+ nreps = (col > 2) ? radc_token(9) + 1 : 1;
+ for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
+ col -= 2;
+ FORYX buf[c][y][x] = PREDICTOR;
+ if (rep & 1) {
+ step = radc_token(10) << 4;
+ FORYX buf[c][y][x] += step;
+ }
+ }
+ } while (nreps == 9);
+ }
+ for (y=0; y < 2; y++)
+ for (x=0; x < width/2; x++) {
+ val = (buf[c][y+1][x] << 4) / mul[c];
+ if (val < 0) val = 0;
+ if (c) BAYER(row+y*2+c-1,x*2+2-c) = val;
+ else BAYER(row+r*2+y,x*2+y) = val;
+ }
+ memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
+ }
+ }
+ for (y=row; y < row+4; y++)
+ for (x=0; x < width; x++)
+ if ((x+y) & 1) {
+ r = x ? x-1 : x+1;
+ s = x+1 < width ? x+1 : x-1;
+ val = (BAYER(y,x)-2048)*2 + (BAYER(y,r)+BAYER(y,s))/2;
+ if (val < 0) val = 0;
+ BAYER(y,x) = val;
+ }
+ }
+ maximum = 0xfff;
+ use_gamma = 0;
+}
+
+#undef FORYX
+#undef PREDICTOR
+
+#ifdef NO_JPEG
+void CLASS kodak_jpeg_load_raw() {}
+#else
+
+METHODDEF(boolean)
+fill_input_buffer (j_decompress_ptr cinfo)
+{
+ static uchar jpeg_buffer[4096];
+ size_t nbytes;
+
+ nbytes = fread (jpeg_buffer, 1, 4096, ifp);
+ swab (jpeg_buffer, jpeg_buffer, nbytes);
+ cinfo->src->next_input_byte = jpeg_buffer;
+ cinfo->src->bytes_in_buffer = nbytes;
+ return TRUE;
+}
+
+void CLASS kodak_jpeg_load_raw()
+{
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ JSAMPARRAY buf;
+ JSAMPLE (*pixel)[3];
+ int row, col;
+
+ cinfo.err = jpeg_std_error (&jerr);
+ jpeg_create_decompress (&cinfo);
+ jpeg_stdio_src (&cinfo, ifp);
+ cinfo.src->fill_input_buffer = fill_input_buffer;
+ jpeg_read_header (&cinfo, TRUE);
+ jpeg_start_decompress (&cinfo);
+ if ((cinfo.output_width != width ) ||
+ (cinfo.output_height*2 != height ) ||
+ (cinfo.output_components != 3 )) {
+ fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
+ jpeg_destroy_decompress (&cinfo);
+ longjmp (failure, 3);
+ }
+ buf = (*cinfo.mem->alloc_sarray)
+ ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
+
+ while (cinfo.output_scanline < cinfo.output_height) {
+ row = cinfo.output_scanline * 2;
+ jpeg_read_scanlines (&cinfo, buf, 1);
+ pixel = (JSAMPLE (*)[3]) buf[0];
+ for (col=0; col < width; col+=2) {
+ BAYER(row+0,col+0) = pixel[col+0][1] << 1;
+ BAYER(row+1,col+1) = pixel[col+1][1] << 1;
+ BAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
+ BAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
+ }
+ }
+ jpeg_finish_decompress (&cinfo);
+ jpeg_destroy_decompress (&cinfo);
+ maximum = 0xff << 1;
+}
+#endif
+
+void CLASS kodak_dc120_load_raw()
+{
+ static const int mul[4] = { 162, 192, 187, 92 };
+ static const int add[4] = { 0, 636, 424, 212 };
+ uchar pixel[848];
+ int row, shift, col;
+
+ for (row=0; row < height; row++) {
+ if (fread (pixel, 1, 848, ifp) < 848) derror();
+ shift = row * mul[row & 3] + add[row & 3];
+ for (col=0; col < width; col++)
+ BAYER(row,col) = (ushort) pixel[(col + shift) % 848];
+ }
+ maximum = 0xff;
+}
+
+void CLASS eight_bit_load_raw()
+{
+ uchar *pixel;
+ unsigned row, col, val, lblack=0;
+
+ pixel = (uchar *) calloc (raw_width, sizeof *pixel);
+ merror (pixel, "eight_bit_load_raw()");
+ fseek (ifp, top_margin*raw_width, SEEK_CUR);
+ for (row=0; row < height; row++) {
+ if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
+ for (col=0; col < raw_width; col++) {
+ val = curve[pixel[col]];
+ if ((unsigned) (col-left_margin) < width)
+ BAYER(row,col-left_margin) = val;
+ else lblack += val;
+ }
+ }
+ free (pixel);
+ if (raw_width > width+1)
+ black = lblack / ((raw_width - width) * height);
+ if (!strncmp(model,"DC2",3))
+ black = 0;
+ maximum = curve[0xff];
+}
+
+void CLASS kodak_262_load_raw()
+{
+ static const uchar kodak_tree[2][26] =
+ { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 },
+ { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } };
+ struct decode *decode[2];
+ uchar *pixel;
+ int *strip, ns, i, row, col, chess, pi=0, pi1, pi2, pred, val;
+
+ init_decoder();
+ for (i=0; i < 2; i++) {
+ decode[i] = free_decode;
+ make_decoder (kodak_tree[i], 0);
+ }
+ ns = (raw_height+63) >> 5;
+ pixel = (uchar *) malloc (raw_width*32 + ns*4);
+ merror (pixel, "kodak_262_load_raw()");
+ strip = (int *) (pixel + raw_width*32);
+ order = 0x4d4d;
+ for (i=0; i < ns; i++)
+ strip[i] = get4();
+ for (row=0; row < raw_height; row++) {
+ if ((row & 31) == 0) {
+ fseek (ifp, strip[row >> 5], SEEK_SET);
+ getbits(-1);
+ pi = 0;
+ }
+ for (col=0; col < raw_width; col++) {
+ chess = (row + col) & 1;
+ pi1 = chess ? pi-2 : pi-raw_width-1;
+ pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
+ if (col <= chess) pi1 = -1;
+ if (pi1 < 0) pi1 = pi2;
+ if (pi2 < 0) pi2 = pi1;
+ if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
+ pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
+ pixel[pi] = val = pred + ljpeg_diff (decode[chess]);
+ if (val >> 8) derror();
+ val = curve[pixel[pi++]];
+ if ((unsigned) (col-left_margin) < width)
+ BAYER(row,col-left_margin) = val;
+ else black += val;
+ }
+ }
+ free (pixel);
+ if (raw_width > width)
+ black /= (raw_width - width) * height;
+}
+
+int CLASS kodak_65000_decode (short *out, int bsize)
+{
+ uchar c, blen[768];
+ ushort raw[6];
+ INT64 bitbuf=0;
+ int save, bits=0, i, j, len, diff;
+
+ save = ftell(ifp);
+ bsize = (bsize + 3) & -4;
+ for (i=0; i < bsize; i+=2) {
+ c = fgetc(ifp);
+ if ((blen[i ] = c & 15) > 12 ||
+ (blen[i+1] = c >> 4) > 12 ) {
+ fseek (ifp, save, SEEK_SET);
+ for (i=0; i < bsize; i+=8) {
+ read_shorts (raw, 6);
+ out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
+ out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
+ for (j=0; j < 6; j++)
+ out[i+2+j] = raw[j] & 0xfff;
+ }
+ return 1;
+ }
+ }
+ if ((bsize & 7) == 4) {
+ bitbuf = fgetc(ifp) << 8;
+ bitbuf += fgetc(ifp);
+ bits = 16;
+ }
+ for (i=0; i < bsize; i++) {
+ len = blen[i];
+ if (bits < len) {
+ for (j=0; j < 32; j+=8)
+ bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
+ bits += 32;
+ }
+ diff = bitbuf & (0xffff >> (16-len));
+ bitbuf >>= len;
+ bits -= len;
+ if ((diff & (1 << (len-1))) == 0)
+ diff -= (1 << len) - 1;
+ out[i] = diff;
+ }
+ return 0;
+}
+
+void CLASS kodak_65000_load_raw()
+{
+ short buf[256];
+ int row, col, len, pred[2], ret, i;
+
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col+=256) {
+ pred[0] = pred[1] = 0;
+ len = MIN (256, width-col);
+ ret = kodak_65000_decode (buf, len);
+ for (i=0; i < len; i++)
+ if ((BAYER(row,col+i) = curve[ret ? buf[i] :
+ (pred[i & 1] += buf[i])]) >> 12) derror();
+ }
+}
+
+void CLASS kodak_ycbcr_load_raw()
+{
+ short buf[384], *bp;
+ int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
+ ushort *ip;
+
+ for (row=0; row < height; row+=2)
+ for (col=0; col < width; col+=128) {
+ len = MIN (128, width-col);
+ kodak_65000_decode (buf, len*3);
+ y[0][1] = y[1][1] = cb = cr = 0;
+ for (bp=buf, i=0; i < len; i+=2, bp+=2) {
+ cb += bp[4];
+ cr += bp[5];
+ rgb[1] = -((cb + cr + 2) >> 2);
+ rgb[2] = rgb[1] + cb;
+ rgb[0] = rgb[1] + cr;
+ for (j=0; j < 2; j++)
+ for (k=0; k < 2; k++) {
+ if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
+ ip = image[(row+j)*width + col+i+k];
+ FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
+ }
+ }
+ }
+}
+
+void CLASS kodak_rgb_load_raw()
+{
+ short buf[768], *bp;
+ int row, col, len, c, i, rgb[3];
+ ushort *ip=image[0];
+
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col+=256) {
+ len = MIN (256, width-col);
+ kodak_65000_decode (buf, len*3);
+ memset (rgb, 0, sizeof rgb);
+ for (bp=buf, i=0; i < len; i++, ip+=4)
+ FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
+ }
+}
+
+void CLASS kodak_thumb_load_raw()
+{
+ int row, col;
+ colors = thumb_misc >> 5;
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++)
+ read_shorts (image[row*width+col], colors);
+ maximum = (1 << (thumb_misc & 31)) - 1;
+}
+
+void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
+{
+ static unsigned pad[128], p;
+
+ if (start) {
+ for (p=0; p < 4; p++)
+ pad[p] = key = key * 48828125 + 1;
+ pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
+ for (p=4; p < 127; p++)
+ pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
+ for (p=0; p < 127; p++)
+ pad[p] = htonl(pad[p]);
+ }
+ while (len--)
+ *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
+}
+
+void CLASS sony_load_raw()
+{
+ uchar head[40];
+ ushort *pixel;
+ unsigned i, key, row, col;
+
+ fseek (ifp, 200896, SEEK_SET);
+ fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
+ order = 0x4d4d;
+ key = get4();
+ fseek (ifp, 164600, SEEK_SET);
+ fread (head, 1, 40, ifp);
+ sony_decrypt ((unsigned int *) head, 10, 1, key);
+ for (i=26; i-- > 22; )
+ key = key << 8 | head[i];
+ fseek (ifp, data_offset, SEEK_SET);
+ pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+ merror (pixel, "sony_load_raw()");
+ for (row=0; row < height; row++) {
+ if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
+ sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
+ for (col=9; col < left_margin; col++)
+ black += ntohs(pixel[col]);
+ for (col=0; col < width; col++)
+ if ((BAYER(row,col) = ntohs(pixel[col+left_margin])) >> 14)
+ derror();
+ }
+ free (pixel);
+ if (left_margin > 9)
+ black /= (left_margin-9) * height;
+ maximum = 0x3ff0;
+}
+
+void CLASS sony_arw_load_raw()
+{
+ int col, row, len, diff, sum=0;
+
+ getbits(-1);
+ for (col = raw_width; col--; )
+ for (row=0; row < raw_height+1; row+=2) {
+ if (row == raw_height) row = 1;
+ len = 4 - getbits(2);
+ if (len == 3 && getbits(1)) len = 0;
+ if (len == 4)
+ while (len < 17 && !getbits(1)) len++;
+ diff = getbits(len);
+ if ((diff & (1 << (len-1))) == 0)
+ diff -= (1 << len) - 1;
+ if ((sum += diff) >> 12) derror();
+ if (row < height) BAYER(row,col) = sum;
+ }
+}
+
+void CLASS sony_arw2_load_raw()
+{
+ uchar *data, *dp;
+ ushort pix[16];
+ int row, col, val, max, min, imax, imin, sh, bit, i;
+
+ data = (uchar *) malloc (raw_width*tiff_bps >> 3);
+ merror (data, "sony_arw2_load_raw()");
+ for (row=0; row < height; row++) {
+ fread (data, 1, raw_width*tiff_bps >> 3, ifp);
+ if (tiff_bps == 8) {
+ for (dp=data, col=0; col < width-30; dp+=16) {
+ max = 0x7ff & (val = sget4(dp));
+ min = 0x7ff & val >> 11;
+ imax = 0x0f & val >> 22;
+ imin = 0x0f & val >> 26;
+ for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
+ for (bit=30, i=0; i < 16; i++)
+ if (i == imax) pix[i] = max;
+ else if (i == imin) pix[i] = min;
+ else {
+ pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
+ if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+ bit += 7;
+ }
+ for (i=0; i < 16; i++, col+=2)
+ BAYER(row,col) = curve[pix[i] << 1] >> 1;
+ col -= col & 1 ? 1:31;
+ }
+ } else if (tiff_bps == 12)
+ for (dp=data, col=0; col < width; dp+=3, col+=2) {
+ BAYER(row,col) = ((dp[1] << 8 | dp[0]) & 0xfff) << 1;
+ BAYER(row,col+1) = (dp[2] << 4 | dp[1] >> 4) << 1;
+ }
+ }
+ free (data);
+ maximum = 0x1fff;
+}
+
+#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
+
+/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
+void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
+{
+ uchar hist[3][13] = {
+ { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
+ { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
+ { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
+ int low, high=0xff, carry=0, nbits=8;
+ int s, count, bin, next, i, sym[3];
+ uchar diff, pred[]={0,0};
+ ushort data=0, range=0;
+ unsigned pix, row, col;
+
+ fseek (ifp, seg[0][1]+1, SEEK_SET);
+ getbits(-1);
+ for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
+ for (s=0; s < 3; s++) {
+ data = data << nbits | getbits(nbits);
+ if (carry < 0)
+ carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
+ while (--nbits >= 0)
+ if ((data >> nbits & 0xff) == 0xff) break;
+ if (nbits > 0)
+ data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
+ ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
+ if (nbits >= 0) {
+ data += getbits(1);
+ carry = nbits - 8;
+ }
+ count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
+ for (bin=0; hist[s][bin+5] > count; bin++);
+ low = hist[s][bin+5] * (high >> 4) >> 2;
+ if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
+ high -= low;
+ for (nbits=0; high << nbits < 128; nbits++);
+ range = (range+low) << nbits;
+ high <<= nbits;
+ next = hist[s][1];
+ if (++hist[s][2] > hist[s][3]) {
+ next = (next+1) & hist[s][0];
+ hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
+ hist[s][2] = 1;
+ }
+ if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
+ if (bin < hist[s][1])
+ for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
+ else if (next <= bin)
+ for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
+ }
+ hist[s][1] = next;
+ sym[s] = bin;
+ }
+ diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
+ if (sym[0] & 4)
+ diff = diff ? -diff : 0x80;
+ if (ftell(ifp) + 12 >= seg[1][1])
+ diff = 0;
+ pred[pix & 1] += diff;
+ row = pix / raw_width - top_margin;
+ col = pix % raw_width - left_margin;
+ if (row < height && col < width)
+ BAYER(row,col) = pred[pix & 1];
+ if (!(pix & 1) && HOLE(row)) pix += 2;
+ }
+ maximum = 0xff;
+}
+
+void CLASS smal_v6_load_raw()
+{
+ unsigned seg[2][2];
+
+ fseek (ifp, 16, SEEK_SET);
+ seg[0][0] = 0;
+ seg[0][1] = get2();
+ seg[1][0] = raw_width * raw_height;
+ seg[1][1] = INT_MAX;
+ smal_decode_segment (seg, 0);
+ use_gamma = 0;
+}
+
+int CLASS median4 (int *p)
+{
+ int min, max, sum, i;
+
+ min = max = sum = p[0];
+ for (i=1; i < 4; i++) {
+ sum += p[i];
+ if (min > p[i]) min = p[i];
+ if (max < p[i]) max = p[i];
+ }
+ return (sum - min - max) >> 1;
+}
+
+void CLASS fill_holes (int holes)
+{
+ int row, col, val[4];
+
+ for (row=2; row < height-2; row++) {
+ if (!HOLE(row)) continue;
+ for (col=1; col < width-1; col+=4) {
+ val[0] = BAYER(row-1,col-1);
+ val[1] = BAYER(row-1,col+1);
+ val[2] = BAYER(row+1,col-1);
+ val[3] = BAYER(row+1,col+1);
+ BAYER(row,col) = median4(val);
+ }
+ for (col=2; col < width-2; col+=4)
+ if (HOLE(row-2) || HOLE(row+2))
+ BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1;
+ else {
+ val[0] = BAYER(row,col-2);
+ val[1] = BAYER(row,col+2);
+ val[2] = BAYER(row-2,col);
+ val[3] = BAYER(row+2,col);
+ BAYER(row,col) = median4(val);
+ }
+ }
+}
+
+void CLASS smal_v9_load_raw()
+{
+ unsigned seg[256][2], offset, nseg, holes, i;
+
+ fseek (ifp, 67, SEEK_SET);
+ offset = get4();
+ nseg = fgetc(ifp);
+ fseek (ifp, offset, SEEK_SET);
+ for (i=0; i < nseg*2; i++)
+ seg[0][i] = get4() + data_offset*(i & 1);
+ fseek (ifp, 78, SEEK_SET);
+ holes = fgetc(ifp);
+ fseek (ifp, 88, SEEK_SET);
+ seg[nseg][0] = raw_height * raw_width;
+ seg[nseg][1] = get4() + data_offset;
+ for (i=0; i < nseg; i++)
+ smal_decode_segment (seg+i, holes);
+ if (holes) fill_holes (holes);
+}
+
+/* RESTRICTED code starts here */
+
+void CLASS foveon_decoder (unsigned size, unsigned code)
+{
+ static unsigned huff[1024];
+ struct decode *cur;
+ int i, len;
+
+ if (!code) {
+ for (i=0; i < size; i++)
+ huff[i] = get4();
+ init_decoder();
+ }
+ cur = free_decode++;
+ if (free_decode > first_decode+2048) {
+ fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
+ longjmp (failure, 2);
+ }
+ if (code)
+ for (i=0; i < size; i++)
+ if (huff[i] == code) {
+ cur->leaf = i;
+ return;
+ }
+ if ((len = code >> 27) > 26) return;
+ code = (len+1) << 27 | (code & 0x3ffffff) << 1;
+
+ cur->branch[0] = free_decode;
+ foveon_decoder (size, code);
+ cur->branch[1] = free_decode;
+ foveon_decoder (size, code+1);
+}
+
+void CLASS foveon_thumb (FILE *tfp)
+{
+ unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
+ char *buf;
+ struct decode *dindex;
+ short pred[3];
+
+ bwide = get4();
+ fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
+ if (bwide > 0) {
+ if (bwide < thumb_width*3) return;
+ buf = (char *) malloc (bwide);
+ merror (buf, "foveon_thumb()");
+ for (row=0; row < thumb_height; row++) {
+ fread (buf, 1, bwide, ifp);
+ fwrite (buf, 3, thumb_width, tfp);
+ }
+ free (buf);
+ return;
+ }
+ foveon_decoder (256, 0);
+
+ for (row=0; row < thumb_height; row++) {
+ memset (pred, 0, sizeof pred);
+ if (!bit) get4();
+ for (bit=col=0; col < thumb_width; col++)
+ FORC3 {
+ for (dindex=first_decode; dindex->branch[0]; ) {
+ if ((bit = (bit-1) & 31) == 31)
+ for (i=0; i < 4; i++)
+ bitbuf = (bitbuf << 8) + fgetc(ifp);
+ dindex = dindex->branch[bitbuf >> bit & 1];
+ }
+ pred[c] += dindex->leaf;
+ fputc (pred[c], tfp);
+ }
+ }
+}
+
+void CLASS foveon_load_camf()
+{
+ unsigned key, i, val;
+
+ fseek (ifp, meta_offset, SEEK_SET);
+ key = get4();
+ fread (meta_data, 1, meta_length, ifp);
+ for (i=0; i < meta_length; i++) {
+ key = (key * 1597 + 51749) % 244944;
+ val = key * (INT64) 301593171 >> 24;
+ meta_data[i] ^= ((((key << 8) - val) >> 1) + val) >> 17;
+ }
+}
+
+void CLASS foveon_load_raw()
+{
+ struct decode *dindex;
+ short diff[1024];
+ unsigned bitbuf=0;
+ int pred[3], fixed, row, col, bit=-1, c, i;
+
+ fixed = get4();
+ read_shorts ((ushort *) diff, 1024);
+ if (!fixed) foveon_decoder (1024, 0);
+
+ for (row=0; row < height; row++) {
+ memset (pred, 0, sizeof pred);
+ if (!bit && !fixed && atoi(model+2) < 14) get4();
+ for (col=bit=0; col < width; col++) {
+ if (fixed) {
+ bitbuf = get4();
+ FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
+ }
+ else FORC3 {
+ for (dindex=first_decode; dindex->branch[0]; ) {
+ if ((bit = (bit-1) & 31) == 31)
+ for (i=0; i < 4; i++)
+ bitbuf = (bitbuf << 8) + fgetc(ifp);
+ dindex = dindex->branch[bitbuf >> bit & 1];
+ }
+ pred[c] += diff[dindex->leaf];
+ if (pred[c] >> 16 && ~pred[c] >> 16) derror();
+ }
+ FORC3 image[row*width+col][c] = pred[c];
+ }
+ }
+ if (document_mode)
+ for (i=0; i < height*width*4; i++)
+ if ((short) image[0][i] < 0) image[0][i] = 0;
+ foveon_load_camf();
+}
+
+const char * CLASS foveon_camf_param (const char *block, const char *param)
+{
+ unsigned idx, num;
+ char *pos, *cp, *dp;
+
+ for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
+ pos = meta_data + idx;
+ if (strncmp (pos, "CMb", 3)) break;
+ if (pos[3] != 'P') continue;
+ if (strcmp (block, pos+sget4(pos+12))) continue;
+ cp = pos + sget4(pos+16);
+ num = sget4(cp);
+ dp = pos + sget4(cp+4);
+ while (num--) {
+ cp += 8;
+ if (!strcmp (param, dp+sget4(cp)))
+ return dp+sget4(cp+4);
+ }
+ }
+ return 0;
+}
+
+void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
+{
+ unsigned i, idx, type, ndim, size, *mat;
+ char *pos, *cp, *dp;
+ double dsize;
+
+ for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
+ pos = meta_data + idx;
+ if (strncmp (pos, "CMb", 3)) break;
+ if (pos[3] != 'M') continue;
+ if (strcmp (name, pos+sget4(pos+12))) continue;
+ dim[0] = dim[1] = dim[2] = 1;
+ cp = pos + sget4(pos+16);
+ type = sget4(cp);
+ if ((ndim = sget4(cp+4)) > 3) break;
+ dp = pos + sget4(cp+8);
+ for (i=ndim; i--; ) {
+ cp += 12;
+ dim[i] = sget4(cp);
+ }
+ if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
+ mat = (unsigned *) malloc ((size = dsize) * 4);
+ merror (mat, "foveon_camf_matrix()");
+ for (i=0; i < size; i++)
+ if (type && type != 6)
+ mat[i] = sget4(dp + i*4);
+ else
+ mat[i] = sget4(dp + i*2) & 0xffff;
+ return mat;
+ }
+ fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
+ return 0;
+}
+
+int CLASS foveon_fixed (void *ptr, int size, const char *name)
+{
+ void *dp;
+ unsigned dim[3];
+
+ dp = foveon_camf_matrix (dim, name);
+ if (!dp) return 0;
+ memcpy (ptr, dp, size*4);
+ free (dp);
+ return 1;
+}
+
+float CLASS foveon_avg (short *pix, int range[2], float cfilt)
+{
+ int i;
+ float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
+
+ for (i=range[0]; i <= range[1]; i++) {
+ sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
+ if (min > val) min = val;
+ if (max < val) max = val;
+ }
+ if (range[1] - range[0] == 1) return sum/2;
+ return (sum - min - max) / (range[1] - range[0] - 1);
+}
+
+short * CLASS foveon_make_curve (double max, double mul, double filt)
+{
+ short *curve;
+ unsigned i, size;
+ double x;
+
+ if (!filt) filt = 0.8;
+ size = 4*M_PI*max / filt;
+ if (size == UINT_MAX) size--;
+ curve = (short *) calloc (size+1, sizeof *curve);
+ merror (curve, "foveon_make_curve()");
+ curve[0] = size;
+ for (i=0; i < size; i++) {
+ x = i*filt/max/4;
+ curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
+ }
+ return curve;
+}
+
+void CLASS foveon_make_curves
+ (short **curvep, float dq[3], float div[3], float filt)
+{
+ double mul[3], max=0;
+ int c;
+
+ FORC3 mul[c] = dq[c]/div[c];
+ FORC3 if (max < mul[c]) max = mul[c];
+ FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
+}
+
+int CLASS foveon_apply_curve (short *curve, int i)
+{
+ if (abs(i) >= curve[0]) return 0;
+ return i < 0 ? -curve[1-i] : curve[1+i];
+}
+
+#define image ((short (*)[4]) image)
+
+void CLASS foveon_interpolate()
+{
+ static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
+ short *pix, prev[3], *curve[8], (*shrink)[3];
+ float cfilt=0, ddft[3][3][2], ppm[3][3][3];
+ float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
+ float chroma_dq[3], color_dq[3], diag[3][3], div[3];
+ float (*black)[3], (*sgain)[3], (*sgrow)[3];
+ float fsum[3], val, frow, num;
+ int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
+ int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
+ int work[3][3], smlast, smred, smred_p=0, dev[3];
+ int satlev[3], keep[4], active[4];
+ unsigned dim[3], *badpix;
+ double dsum=0, trsum[3];
+ char str[128];
+ const char* cp;
+
+ if (verbose)
+ fprintf (stderr,_("Foveon interpolation...\n"));
+
+ foveon_fixed (dscr, 4, "DarkShieldColRange");
+ foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
+ foveon_fixed (satlev, 3, "SaturationLevel");
+ foveon_fixed (keep, 4, "KeepImageArea");
+ foveon_fixed (active, 4, "ActiveImageArea");
+ foveon_fixed (chroma_dq, 3, "ChromaDQ");
+ foveon_fixed (color_dq, 3,
+ foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
+ "ColorDQ" : "ColorDQCamRGB");
+ if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
+ foveon_fixed (&cfilt, 1, "ColumnFilter");
+
+ memset (ddft, 0, sizeof ddft);
+ if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
+ || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
+ for (i=0; i < 2; i++) {
+ foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
+ for (row = dstb[1]; row <= dstb[3]; row++)
+ for (col = dstb[0]; col <= dstb[2]; col++)
+ FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
+ FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
+ }
+
+ if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
+ { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
+ return; }
+ foveon_fixed (cam_xyz, 9, cp);
+ foveon_fixed (correct, 9,
+ foveon_camf_param ("WhiteBalanceCorrections", model2));
+ memset (last, 0, sizeof last);
+ for (i=0; i < 3; i++)
+ for (j=0; j < 3; j++)
+ FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
+
+ #define LAST(x,y) last[(i+x)%3][(c+y)%3]
+ for (i=0; i < 3; i++)
+ FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
+ #undef LAST
+ FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
+ sprintf (str, "%sRGBNeutral", model2);
+ if (foveon_camf_param ("IncludeBlocks", str))
+ foveon_fixed (div, 3, str);
+ num = 0;
+ FORC3 if (num < div[c]) num = div[c];
+ FORC3 div[c] /= num;
+
+ memset (trans, 0, sizeof trans);
+ for (i=0; i < 3; i++)
+ for (j=0; j < 3; j++)
+ FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
+ FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
+ dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
+ for (i=0; i < 3; i++)
+ FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
+ memset (trans, 0, sizeof trans);
+ for (i=0; i < 3; i++)
+ for (j=0; j < 3; j++)
+ FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
+
+ foveon_make_curves (curve, color_dq, div, cfilt);
+ FORC3 chroma_dq[c] /= 3;
+ foveon_make_curves (curve+3, chroma_dq, div, cfilt);
+ FORC3 dsum += chroma_dq[c] / div[c];
+ curve[6] = foveon_make_curve (dsum, dsum, cfilt);
+ curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
+
+ sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
+ if (!sgain) return;
+ sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
+ sgx = (width + dim[1]-2) / (dim[1]-1);
+
+ black = (float (*)[3]) calloc (height, sizeof *black);
+ for (row=0; row < height; row++) {
+ for (i=0; i < 6; i++)
+ ddft[0][0][i] = ddft[1][0][i] +
+ row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
+ FORC3 black[row][c] =
+ ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
+ foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
+ - ddft[0][c][0] ) / 4 - ddft[0][c][1];
+ }
+ memcpy (black, black+8, sizeof *black*8);
+ memcpy (black+height-11, black+height-22, 11*sizeof *black);
+ memcpy (last, black, sizeof last);
+
+ for (row=1; row < height-1; row++) {
+ FORC3 if (last[1][c] > last[0][c]) {
+ if (last[1][c] > last[2][c])
+ black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
+ } else
+ if (last[1][c] < last[2][c])
+ black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
+ memmove (last, last+1, 2*sizeof last[0]);
+ memcpy (last[2], black[row+1], sizeof last[2]);
+ }
+ FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
+ FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
+
+ val = 1 - exp(-1/24.0);
+ memcpy (fsum, black, sizeof fsum);
+ for (row=1; row < height; row++)
+ FORC3 fsum[c] += black[row][c] =
+ (black[row][c] - black[row-1][c])*val + black[row-1][c];
+ memcpy (last[0], black[height-1], sizeof last[0]);
+ FORC3 fsum[c] /= height;
+ for (row = height; row--; )
+ FORC3 last[0][c] = black[row][c] =
+ (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
+
+ memset (total, 0, sizeof total);
+ for (row=2; row < height; row+=4)
+ for (col=2; col < width; col+=4) {
+ FORC3 total[c] += (short) image[row*width+col][c];
+ total[3]++;
+ }
+ for (row=0; row < height; row++)
+ FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
+
+ for (row=0; row < height; row++) {
+ for (i=0; i < 6; i++)
+ ddft[0][0][i] = ddft[1][0][i] +
+ row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
+ pix = image[row*width];
+ memcpy (prev, pix, sizeof prev);
+ frow = row / (height-1.0) * (dim[2]-1);
+ if ((irow = frow) == dim[2]-1) irow--;
+ frow -= irow;
+ for (i=0; i < dim[1]; i++)
+ FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
+ sgain[(irow+1)*dim[1]+i][c] * frow;
+ for (col=0; col < width; col++) {
+ FORC3 {
+ diff = pix[c] - prev[c];
+ prev[c] = pix[c];
+ ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
+ - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
+ - black[row][c] );
+ }
+ FORC3 {
+ work[0][c] = ipix[c] * ipix[c] >> 14;
+ work[2][c] = ipix[c] * work[0][c] >> 14;
+ work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
+ }
+ FORC3 {
+ for (val=i=0; i < 3; i++)
+ for ( j=0; j < 3; j++)
+ val += ppm[c][i][j] * work[i][j];
+ ipix[c] = floor ((ipix[c] + floor(val)) *
+ ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
+ sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
+ if (ipix[c] > 32000) ipix[c] = 32000;
+ pix[c] = ipix[c];
+ }
+ pix += 4;
+ }
+ }
+ free (black);
+ free (sgrow);
+ free (sgain);
+
+ if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) {
+ for (i=0; i < dim[0]; i++) {
+ col = (badpix[i] >> 8 & 0xfff) - keep[0];
+ row = (badpix[i] >> 20 ) - keep[1];
+ if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
+ continue;
+ memset (fsum, 0, sizeof fsum);
+ for (sum=j=0; j < 8; j++)
+ if (badpix[i] & (1 << j)) {
+ FORC3 fsum[c] += (short)
+ image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
+ sum++;
+ }
+ if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
+ }
+ free (badpix);
+ }
+
+ /* Array for 5x5 Gaussian averaging of red values */
+ smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
+ merror (smrow[6], "foveon_interpolate()");
+ for (i=0; i < 5; i++)
+ smrow[i] = smrow[6] + i*width;
+
+ /* Sharpen the reds against these Gaussian averages */
+ for (smlast=-1, row=2; row < height-2; row++) {
+ while (smlast < row+2) {
+ for (i=0; i < 6; i++)
+ smrow[(i+5) % 6] = smrow[i];
+ pix = image[++smlast*width+2];
+ for (col=2; col < width-2; col++) {
+ smrow[4][col][0] =
+ (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
+ pix += 4;
+ }
+ }
+ pix = image[row*width+2];
+ for (col=2; col < width-2; col++) {
+ smred = ( 6 * smrow[2][col][0]
+ + 4 * (smrow[1][col][0] + smrow[3][col][0])
+ + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
+ if (col == 2)
+ smred_p = smred;
+ i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
+ if (i > 32000) i = 32000;
+ pix[0] = i;
+ smred_p = smred;
+ pix += 4;
+ }
+ }
+
+ /* Adjust the brighter pixels for better linearity */
+ min = 0xffff;
+ FORC3 {
+ i = satlev[c] / div[c];
+ if (min > i) min = i;
+ }
+ limit = min * 9 >> 4;
+ for (pix=image[0]; pix < image[height*width]; pix+=4) {
+ if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
+ continue;
+ min = max = pix[0];
+ for (c=1; c < 3; c++) {
+ if (min > pix[c]) min = pix[c];
+ if (max < pix[c]) max = pix[c];
+ }
+ if (min >= limit*2) {
+ pix[0] = pix[1] = pix[2] = max;
+ } else {
+ i = 0x4000 - ((min - limit) << 14) / limit;
+ i = 0x4000 - (i*i >> 14);
+ i = i*i >> 14;
+ FORC3 pix[c] += (max - pix[c]) * i >> 14;
+ }
+ }
+/*
+ Because photons that miss one detector often hit another,
+ the sum R+G+B is much less noisy than the individual colors.
+ So smooth the hues without smoothing the total.
+ */
+ for (smlast=-1, row=2; row < height-2; row++) {
+ while (smlast < row+2) {
+ for (i=0; i < 6; i++)
+ smrow[(i+5) % 6] = smrow[i];
+ pix = image[++smlast*width+2];
+ for (col=2; col < width-2; col++) {
+ FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
+ pix += 4;
+ }
+ }
+ pix = image[row*width+2];
+ for (col=2; col < width-2; col++) {
+ FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
+ ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
+ sum = (dev[0] + dev[1] + dev[2]) >> 3;
+ FORC3 pix[c] += dev[c] - sum;
+ pix += 4;
+ }
+ }
+ for (smlast=-1, row=2; row < height-2; row++) {
+ while (smlast < row+2) {
+ for (i=0; i < 6; i++)
+ smrow[(i+5) % 6] = smrow[i];
+ pix = image[++smlast*width+2];
+ for (col=2; col < width-2; col++) {
+ FORC3 smrow[4][col][c] =
+ (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
+ pix += 4;
+ }
+ }
+ pix = image[row*width+2];
+ for (col=2; col < width-2; col++) {
+ for (total[3]=375, sum=60, c=0; c < 3; c++) {
+ for (total[c]=i=0; i < 5; i++)
+ total[c] += smrow[i][col][c];
+ total[3] += total[c];
+ sum += pix[c];
+ }
+ if (sum < 0) sum = 0;
+ j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
+ FORC3 pix[c] += foveon_apply_curve (curve[6],
+ ((j*total[c] + 0x8000) >> 16) - pix[c]);
+ pix += 4;
+ }
+ }
+
+ /* Transform the image to a different colorspace */
+ for (pix=image[0]; pix < image[height*width]; pix+=4) {
+ FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
+ sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
+ FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
+ FORC3 {
+ for (dsum=i=0; i < 3; i++)
+ dsum += trans[c][i] * pix[i];
+ if (dsum < 0) dsum = 0;
+ if (dsum > 24000) dsum = 24000;
+ ipix[c] = dsum + 0.5;
+ }
+ FORC3 pix[c] = ipix[c];
+ }
+
+ /* Smooth the image bottom-to-top and save at 1/4 scale */
+ shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink);
+ merror (shrink, "foveon_interpolate()");
+ for (row = height/4; row--; )
+ for (col=0; col < width/4; col++) {
+ ipix[0] = ipix[1] = ipix[2] = 0;
+ for (i=0; i < 4; i++)
+ for (j=0; j < 4; j++)
+ FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
+ FORC3
+ if (row+2 > height/4)
+ shrink[row*(width/4)+col][c] = ipix[c] >> 4;
+ else
+ shrink[row*(width/4)+col][c] =
+ (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
+ }
+ /* From the 1/4-scale image, smooth right-to-left */
+ for (row=0; row < (height & ~3); row++) {
+ ipix[0] = ipix[1] = ipix[2] = 0;
+ if ((row & 3) == 0)
+ for (col = width & ~3 ; col--; )
+ FORC3 smrow[0][col][c] = ipix[c] =
+ (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
+
+ /* Then smooth left-to-right */
+ ipix[0] = ipix[1] = ipix[2] = 0;
+ for (col=0; col < (width & ~3); col++)
+ FORC3 smrow[1][col][c] = ipix[c] =
+ (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
+
+ /* Smooth top-to-bottom */
+ if (row == 0)
+ memcpy (smrow[2], smrow[1], sizeof **smrow * width);
+ else
+ for (col=0; col < (width & ~3); col++)
+ FORC3 smrow[2][col][c] =
+ (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
+
+ /* Adjust the chroma toward the smooth values */
+ for (col=0; col < (width & ~3); col++) {
+ for (i=j=30, c=0; c < 3; c++) {
+ i += smrow[2][col][c];
+ j += image[row*width+col][c];
+ }
+ j = (j << 16) / i;
+ for (sum=c=0; c < 3; c++) {
+ ipix[c] = foveon_apply_curve (curve[c+3],
+ ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
+ sum += ipix[c];
+ }
+ sum >>= 3;
+ FORC3 {
+ i = image[row*width+col][c] + ipix[c] - sum;
+ if (i < 0) i = 0;
+ image[row*width+col][c] = i;
+ }
+ }
+ }
+ free (shrink);
+ free (smrow[6]);
+ for (i=0; i < 8; i++)
+ free (curve[i]);
+
+ /* Trim off the black border */
+ active[1] -= keep[1];
+ active[3] -= 2;
+ i = active[2] - active[0];
+ for (row=0; row < active[3]-active[1]; row++)
+ memcpy (image[row*i], image[(row+active[1])*width+active[0]],
+ i * sizeof *image);
+ width = i;
+ height = row;
+}
+#undef image
+
+/* RESTRICTED code ends here */
+
+/*
+ Seach from the current directory up to the root looking for
+ a ".badpixels" file, and fix those pixels now.
+ */
+void CLASS bad_pixels()
+{
+ FILE *fp=0;
+ char *fname, *cp, line[128];
+ int len, time, row, col, r, c, rad, tot, n, fixed=0;
+
+ if (!filters) return;
+ for (len=32 ; ; len *= 2) {
+ fname = (char *) malloc (len);
+ if (!fname) return;
+ if (getcwd (fname, len-16)) break;
+ free (fname);
+ if (errno != ERANGE) return;
+ }
+#if defined(WIN32) || defined(DJGPP)
+ if (fname[1] == ':')
+ memmove (fname, fname+2, len-2);
+ for (cp=fname; *cp; cp++)
+ if (*cp == '\\') *cp = '/';
+#endif
+ cp = fname + strlen(fname);
+ if (cp[-1] == '/') cp--;
+ while (*fname == '/') {
+ strcpy (cp, "/.badpixels");
+ if ((fp = fopen (fname, "r"))) break;
+ if (cp == fname) break;
+ while (*--cp != '/');
+ }
+ free (fname);
+ if (!fp) return;
+ while (fgets (line, 128, fp)) {
+ cp = strchr (line, '#');
+ if (cp) *cp = 0;
+ if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
+ if ((unsigned) col >= width || (unsigned) row >= height) continue;
+ if (time > timestamp) continue;
+ for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
+ for (r = row-rad; r <= row+rad; r++)
+ for (c = col-rad; c <= col+rad; c++)
+ if ((unsigned) r < height && (unsigned) c < width &&
+ (r != row || c != col) && fc(r,c) == fc(row,col)) {
+ tot += BAYER2(r,c);
+ n++;
+ }
+ BAYER2(row,col) = tot/n;
+ if (verbose) {
+ if (!fixed++)
+ fprintf (stderr,_("Fixed bad pixels at:"));
+ fprintf (stderr, " %d,%d", col, row);
+ }
+ }
+ if (fixed) fputc ('\n', stderr);
+ fclose (fp);
+}
+
+void CLASS subtract (char *fname)
+{
+ FILE *fp;
+ int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
+ ushort *pixel;
+
+ if (!(fp = fopen (fname, "rb"))) {
+ perror (fname); return;
+ }
+ if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
+ while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
+ if (c == '#') comment = 1;
+ if (c == '\n') comment = 0;
+ if (comment) continue;
+ if (isdigit(c)) number = 1;
+ if (number) {
+ if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
+ else if (isspace(c)) {
+ number = 0; nd++;
+ } else error = 1;
+ }
+ }
+ if (error || nd < 3) {
+ fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
+ fclose (fp); return;
+ } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
+ fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
+ fclose (fp); return;
+ }
+ pixel = (ushort *) calloc (width, sizeof *pixel);
+ merror (pixel, "subtract()");
+ for (row=0; row < height; row++) {
+ fread (pixel, 2, width, fp);
+ for (col=0; col < width; col++)
+ BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
+ }
+ free (pixel);
+ black = 0;
+}
+
+void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
+{
+ double work[3][6], num;
+ int i, j, k;
+
+ for (i=0; i < 3; i++) {
+ for (j=0; j < 6; j++)
+ work[i][j] = j == i+3;
+ for (j=0; j < 3; j++)
+ for (k=0; k < size; k++)
+ work[i][j] += in[k][i] * in[k][j];
+ }
+ for (i=0; i < 3; i++) {
+ num = work[i][i];
+ for (j=0; j < 6; j++)
+ work[i][j] /= num;
+ for (k=0; k < 3; k++) {
+ if (k==i) continue;
+ num = work[k][i];
+ for (j=0; j < 6; j++)
+ work[k][j] -= work[i][j] * num;
+ }
+ }
+ for (i=0; i < size; i++)
+ for (j=0; j < 3; j++)
+ for (out[i][j]=k=0; k < 3; k++)
+ out[i][j] += work[j][k+3] * in[i][k];
+}
+
+void CLASS cam_xyz_coeff (double cam_xyz[4][3])
+{
+ double cam_rgb[4][3], inverse[4][3], num;
+ int i, j, k;
+
+ for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
+ for (j=0; j < 3; j++)
+ for (cam_rgb[i][j] = k=0; k < 3; k++)
+ cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
+
+ for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
+ for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
+ num += cam_rgb[i][j];
+ for (j=0; j < 3; j++)
+ cam_rgb[i][j] /= num;
+ pre_mul[i] = 1 / num;
+ }
+ pseudoinverse (cam_rgb, inverse, colors);
+ for (raw_color = i=0; i < 3; i++)
+ for (j=0; j < colors; j++)
+ rgb_cam[i][j] = inverse[j][i];
+}
+
+#ifdef COLORCHECK
+void CLASS colorcheck()
+{
+#define NSQ 24
+// Coordinates of the GretagMacbeth ColorChecker squares
+// width, height, 1st_column, 1st_row
+ static const int cut[NSQ][4] = {
+ { 241, 231, 234, 274 },
+ { 251, 235, 534, 274 },
+ { 255, 239, 838, 272 },
+ { 255, 240, 1146, 274 },
+ { 251, 237, 1452, 278 },
+ { 243, 238, 1758, 288 },
+ { 253, 253, 218, 558 },
+ { 255, 249, 524, 562 },
+ { 261, 253, 830, 562 },
+ { 260, 255, 1144, 564 },
+ { 261, 255, 1450, 566 },
+ { 247, 247, 1764, 576 },
+ { 255, 251, 212, 862 },
+ { 259, 259, 518, 862 },
+ { 263, 261, 826, 864 },
+ { 265, 263, 1138, 866 },
+ { 265, 257, 1450, 872 },
+ { 257, 255, 1762, 874 },
+ { 257, 253, 212, 1164 },
+ { 262, 251, 516, 1172 },
+ { 263, 257, 826, 1172 },
+ { 263, 255, 1136, 1176 },
+ { 255, 252, 1452, 1182 },
+ { 257, 253, 1760, 1180 } };
+// ColorChecker Chart under 6500-kelvin illumination
+ static const double gmb_xyY[NSQ][3] = {
+ { 0.400, 0.350, 10.1 }, // Dark Skin
+ { 0.377, 0.345, 35.8 }, // Light Skin
+ { 0.247, 0.251, 19.3 }, // Blue Sky
+ { 0.337, 0.422, 13.3 }, // Foliage
+ { 0.265, 0.240, 24.3 }, // Blue Flower
+ { 0.261, 0.343, 43.1 }, // Bluish Green
+ { 0.506, 0.407, 30.1 }, // Orange
+ { 0.211, 0.175, 12.0 }, // Purplish Blue
+ { 0.453, 0.306, 19.8 }, // Moderate Red
+ { 0.285, 0.202, 6.6 }, // Purple
+ { 0.380, 0.489, 44.3 }, // Yellow Green
+ { 0.473, 0.438, 43.1 }, // Orange Yellow
+ { 0.187, 0.129, 6.1 }, // Blue
+ { 0.305, 0.478, 23.4 }, // Green
+ { 0.539, 0.313, 12.0 }, // Red
+ { 0.448, 0.470, 59.1 }, // Yellow
+ { 0.364, 0.233, 19.8 }, // Magenta
+ { 0.196, 0.252, 19.8 }, // Cyan
+ { 0.310, 0.316, 90.0 }, // White
+ { 0.310, 0.316, 59.1 }, // Neutral 8
+ { 0.310, 0.316, 36.2 }, // Neutral 6.5
+ { 0.310, 0.316, 19.8 }, // Neutral 5
+ { 0.310, 0.316, 9.0 }, // Neutral 3.5
+ { 0.310, 0.316, 3.1 } }; // Black
+ double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
+ double inverse[NSQ][3], cam_xyz[4][3], num;
+ int c, i, j, k, sq, row, col, count[4];
+
+ memset (gmb_cam, 0, sizeof gmb_cam);
+ for (sq=0; sq < NSQ; sq++) {
+ FORCC count[c] = 0;
+ for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
+ for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
+ c = FC(row,col);
+ if (c >= colors) c -= 2;
+ gmb_cam[sq][c] += BAYER(row,col);
+ count[c]++;
+ }
+ FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
+ gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
+ gmb_xyz[sq][1] = gmb_xyY[sq][2];
+ gmb_xyz[sq][2] = gmb_xyY[sq][2] *
+ (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
+ }
+ pseudoinverse (gmb_xyz, inverse, NSQ);
+ for (i=0; i < colors; i++)
+ for (j=0; j < 3; j++)
+ for (cam_xyz[i][j] = k=0; k < NSQ; k++)
+ cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
+ cam_xyz_coeff (cam_xyz);
+ if (verbose) {
+ printf (" { \"%s %s\", %d,\n\t{", make, model, black);
+ num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
+ FORCC for (j=0; j < 3; j++)
+ printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
+ puts (" } },");
+ }
+#undef NSQ
+}
+#endif
+
+void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
+{
+ int i;
+ for (i=0; i < sc; i++)
+ temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
+ for (; i+sc < size; i++)
+ temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
+ for (; i < size; i++)
+ temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
+}
+
+void CLASS wavelet_denoise()
+{
+ float *fimg=0, *temp, thold, mul[2], avg, diff;
+ int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast;
+ ushort *window[4];
+ static const float noise[] =
+ { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
+
+ if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
+
+ while (maximum << scale < 0x10000) scale++;
+ maximum <<= --scale;
+ black <<= scale;
+ if ((size = iheight*iwidth) < 0x15550000)
+ fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
+ merror (fimg, "wavelet_denoise()");
+ temp = fimg + size*3;
+ if ((nc = colors) == 3 && filters) nc++;
+ for (c=0; c < nc; c++) { /* denoise R,G1,B,G3 individually */
+ for (i=0; i < size; i++)
+ fimg[i] = sqrt((unsigned) (image[i][c] << (scale+16)));
+ for (hpass=lev=0; lev < 5; lev++) {
+ lpass = size*((lev & 1)+1);
+ for (row=0; row < iheight; row++) {
+ hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
+ for (col=0; col < iwidth; col++)
+ fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
+ }
+ for (col=0; col < iwidth; col++) {
+ hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
+ for (row=0; row < iheight; row++)
+ fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
+ }
+ thold = threshold * noise[lev];
+ for (i=0; i < size; i++) {
+ fimg[hpass+i] -= fimg[lpass+i];
+ if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
+ else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
+ else fimg[hpass+i] = 0;
+ if (hpass) fimg[i] += fimg[hpass+i];
+ }
+ hpass = lpass;
+ }
+ for (i=0; i < size; i++)
+ image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
+ }
+ if (filters && colors == 3) { /* pull G1 and G3 closer together */
+ for (row=0; row < 2; row++)
+ mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
+ for (i=0; i < 4; i++)
+ window[i] = (ushort *) fimg + width*i;
+ for (wlast=-1, row=1; row < height-1; row++) {
+ while (wlast < row+1) {
+ for (wlast++, i=0; i < 4; i++)
+ window[(i+3) & 3] = window[i];
+ for (col = FC(wlast,1) & 1; col < width; col+=2)
+ window[2][col] = BAYER(wlast,col);
+ }
+ thold = threshold/512;
+ for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
+ avg = ( window[0][col-1] + window[0][col+1] +
+ window[2][col-1] + window[2][col+1] - black*4 )
+ * mul[row & 1] + (window[1][col] - black) * 0.5 + black;
+ avg = avg < 0 ? 0 : sqrt(avg);
+ diff = sqrt(BAYER(row,col)) - avg;
+ if (diff < -thold) diff += thold;
+ else if (diff > thold) diff -= thold;
+ else diff = 0;
+ BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
+ }
+ }
+ }
+ free (fimg);
+}
+
+void CLASS scale_colors()
+{
+ unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
+ int val, dblack;
+ double dsum[8], dmin, dmax;
+ float scale_mul[4], fr, fc;
+ ushort *img=0, *pix;
+
+ if (user_mul[0])
+ memcpy (pre_mul, user_mul, sizeof pre_mul);
+ if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
+ memset (dsum, 0, sizeof dsum);
+ bottom = MIN (greybox[1]+greybox[3], height);
+ right = MIN (greybox[0]+greybox[2], width);
+ for (row=greybox[1]; row < bottom; row += 8)
+ for (col=greybox[0]; col < right; col += 8) {
+ memset (sum, 0, sizeof sum);
+ for (y=row; y < row+8 && y < bottom; y++)
+ for (x=col; x < col+8 && x < right; x++)
+ FORC4 {
+ if (filters) {
+ c = FC(y,x);
+ val = BAYER(y,x);
+ } else
+ val = image[y*width+x][c];
+ if (val > maximum-25) goto skip_block;
+ if ((val -= black) < 0) val = 0;
+ sum[c] += val;
+ sum[c+4]++;
+ if (filters) break;
+ }
+ for (c=0; c < 8; c++) dsum[c] += sum[c];
+skip_block: ;
+ }
+ FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
+ }
+ if (use_camera_wb && cam_mul[0] != -1) {
+ memset (sum, 0, sizeof sum);
+ for (row=0; row < 8; row++)
+ for (col=0; col < 8; col++) {
+ c = FC(row,col);
+ if ((val = white[row][col] - black) > 0)
+ sum[c] += val;
+ sum[c+4]++;
+ }
+ if (sum[0] && sum[1] && sum[2] && sum[3])
+ FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
+ else if (cam_mul[0] && cam_mul[2])
+ memcpy (pre_mul, cam_mul, sizeof pre_mul);
+ else
+ fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
+ }
+ if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
+ dblack = black;
+ if (threshold) wavelet_denoise();
+ maximum -= black;
+ for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
+ if (dmin > pre_mul[c])
+ dmin = pre_mul[c];
+ if (dmax < pre_mul[c])
+ dmax = pre_mul[c];
+ }
+ if (!highlight) dmax = dmin;
+ FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
+ if (verbose) {
+ fprintf (stderr,_("Scaling with black %d, multipliers"), dblack);
+ FORC4 fprintf (stderr, " %f", pre_mul[c]);
+ fputc ('\n', stderr);
+ }
+ size = iheight*iwidth;
+ for (i=0; i < size*4; i++) {
+ val = image[0][i];
+ if (!val) continue;
+ val -= black;
+ val *= scale_mul[i & 3];
+ image[0][i] = CLIP(val);
+ }
+ if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
+ if (verbose)
+ fprintf (stderr,_("Correcting chromatic aberration...\n"));
+ for (c=0; c < 4; c+=2) {
+ if (aber[c] == 1) continue;
+ img = (ushort *) malloc (size * sizeof *img);
+ merror (img, "scale_colors()");
+ for (i=0; i < size; i++)
+ img[i] = image[i][c];
+ for (row=0; row < iheight; row++) {
+ ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
+ if (ur > iheight-2) continue;
+ fr -= ur;
+ for (col=0; col < iwidth; col++) {
+ uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
+ if (uc > iwidth-2) continue;
+ fc -= uc;
+ pix = img + ur*iwidth + uc;
+ image[row*iwidth+col][c] =
+ (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
+ (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
+ }
+ }
+ free(img);
+ }
+ }
+}
+
+void CLASS pre_interpolate()
+{
+ ushort (*img)[4];
+ int row, col, c;
+
+ if (shrink) {
+ if (half_size) {
+ height = iheight;
+ width = iwidth;
+ } else {
+ img = (ushort (*)[4]) calloc (height*width, sizeof *img);
+ merror (img, "unshrink()");
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++) {
+ c = fc(row,col);
+ img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
+ }
+ free (image);
+ image = img;
+ shrink = 0;
+ }
+ }
+ if (filters && colors == 3) {
+ if ((mix_green = four_color_rgb)) colors++;
+ else {
+ for (row = FC(1,0) >> 1; row < height; row+=2)
+ for (col = FC(row,1) & 1; col < width; col+=2)
+ image[row*width+col][1] = image[row*width+col][3];
+ filters &= ~((filters & 0x55555555) << 1);
+ }
+ }
+ if (half_size) filters = 0;
+}
+
+void CLASS border_interpolate (int border)
+{
+ unsigned row, col, y, x, f, c, sum[8];
+
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++) {
+ if (col==border && row >= border && row < height-border)
+ col = width-border;
+ memset (sum, 0, sizeof sum);
+ for (y=row-1; y != row+2; y++)
+ for (x=col-1; x != col+2; x++)
+ if (y < height && x < width) {
+ f = fc(y,x);
+ sum[f] += image[y*width+x][f];
+ sum[f+4]++;
+ }
+ f = fc(row,col);
+ FORCC if (c != f && sum[c+4])
+ image[row*width+col][c] = sum[c] / sum[c+4];
+ }
+}
+
+void CLASS lin_interpolate()
+{
+ int code[16][16][32], *ip, sum[4];
+ int c, i, x, y, row, col, shift, color;
+ ushort *pix;
+
+ if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
+
+ border_interpolate(1);
+ for (row=0; row < 16; row++)
+ for (col=0; col < 16; col++) {
+ ip = code[row][col];
+ memset (sum, 0, sizeof sum);
+ for (y=-1; y <= 1; y++)
+ for (x=-1; x <= 1; x++) {
+ shift = (y==0) + (x==0);
+ if (shift == 2) continue;
+ color = fc(row+y,col+x);
+ *ip++ = (width*y + x)*4 + color;
+ *ip++ = shift;
+ *ip++ = color;
+ sum[color] += 1 << shift;
+ }
+ FORCC
+ if (c != fc(row,col)) {
+ *ip++ = c;
+ *ip++ = 256 / sum[c];
+ }
+ }
+ for (row=1; row < height-1; row++)
+ for (col=1; col < width-1; col++) {
+ pix = image[row*width+col];
+ ip = code[row & 15][col & 15];
+ memset (sum, 0, sizeof sum);
+ for (i=8; i--; ip+=3)
+ sum[ip[2]] += pix[ip[0]] << ip[1];
+ for (i=colors; --i; ip+=2)
+ pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
+ }
+}
+
+/*
+ This algorithm is officially called:
+
+ "Interpolation using a Threshold-based variable number of gradients"
+
+ described in http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html
+
+ I've extended the basic idea to work with non-Bayer filter arrays.
+ Gradients are numbered clockwise from NW=0 to W=7.
+ */
+void CLASS vng_interpolate()
+{
+ static const signed char *cp, terms[] = {
+ -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
+ -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
+ -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
+ -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
+ -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
+ -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
+ -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
+ -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
+ -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
+ -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
+ -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
+ -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
+ -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
+ +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
+ +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
+ +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
+ +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
+ +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
+ +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
+ +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
+ +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
+ +1,+0,+2,+1,0,0x10
+ }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
+ ushort (*brow[5])[4], *pix;
+ int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
+ int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
+ int g, diff, thold, num, c;
+
+ lin_interpolate();
+ if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
+
+ if (filters == 1) prow = pcol = 15;
+ ip = (int *) calloc ((prow+1)*(pcol+1), 1280);
+ merror (ip, "vng_interpolate()");
+ for (row=0; row <= prow; row++) /* Precalculate for VNG */
+ for (col=0; col <= pcol; col++) {
+ code[row][col] = ip;
+ for (cp=terms, t=0; t < 64; t++) {
+ y1 = *cp++; x1 = *cp++;
+ y2 = *cp++; x2 = *cp++;
+ weight = *cp++;
+ grads = *cp++;
+ color = fc(row+y1,col+x1);
+ if (fc(row+y2,col+x2) != color) continue;
+ diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1;
+ if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
+ *ip++ = (y1*width + x1)*4 + color;
+ *ip++ = (y2*width + x2)*4 + color;
+ *ip++ = weight;
+ for (g=0; g < 8; g++)
+ if (grads & 1<<g) *ip++ = g;
+ *ip++ = -1;
+ }
+ *ip++ = INT_MAX;
+ for (cp=chood, g=0; g < 8; g++) {
+ y = *cp++; x = *cp++;
+ *ip++ = (y*width + x) * 4;
+ color = fc(row,col);
+ if (fc(row+y,col+x) != color && fc(row+y*2,col+x*2) == color)
+ *ip++ = (y*width + x) * 8 + color;
+ else
+ *ip++ = 0;
+ }
+ }
+ brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
+ merror (brow[4], "vng_interpolate()");
+ for (row=0; row < 3; row++)
+ brow[row] = brow[4] + row*width;
+ for (row=2; row < height-2; row++) { /* Do VNG interpolation */
+ for (col=2; col < width-2; col++) {
+ pix = image[row*width+col];
+ ip = code[row & prow][col & pcol];
+ memset (gval, 0, sizeof gval);
+ while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
+ diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
+ gval[ip[3]] += diff;
+ ip += 5;
+ if ((g = ip[-1]) == -1) continue;
+ gval[g] += diff;
+ while ((g = *ip++) != -1)
+ gval[g] += diff;
+ }
+ ip++;
+ gmin = gmax = gval[0]; /* Choose a threshold */
+ for (g=1; g < 8; g++) {
+ if (gmin > gval[g]) gmin = gval[g];
+ if (gmax < gval[g]) gmax = gval[g];
+ }
+ if (gmax == 0) {
+ memcpy (brow[2][col], pix, sizeof *image);
+ continue;
+ }
+ thold = gmin + (gmax >> 1);
+ memset (sum, 0, sizeof sum);
+ color = fc(row,col);
+ for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
+ if (gval[g] <= thold) {
+ FORCC
+ if (c == color && ip[1])
+ sum[c] += (pix[c] + pix[ip[1]]) >> 1;
+ else
+ sum[c] += pix[ip[0] + c];
+ num++;
+ }
+ }
+ FORCC { /* Save to buffer */
+ t = pix[color];
+ if (c != color)
+ t += (sum[c] - sum[color]) / num;
+ brow[2][col][c] = CLIP(t);
+ }
+ }
+ if (row > 3) /* Write buffer to image */
+ memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
+ for (g=0; g < 4; g++)
+ brow[(g-1) & 3] = brow[g];
+ }
+ memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
+ memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
+ free (brow[4]);
+ free (code[0][0]);
+}
+
+/*
+ Patterned Pixel Grouping Interpolation by Alain Desbiolles
+*/
+void CLASS ppg_interpolate()
+{
+ int gr[4], dir[5] = { 1, width, -1, -width, 1 };
+ int row, col, avg, diff[2], guess[2], c, d, i;
+ static const short sort[] = { 0,2,1,3,0,1,2,3 };
+ ushort (*pix)[4];
+
+ border_interpolate(3);
+ if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
+
+/* Fill in the green layer with gradients and pattern recognition: */
+ for (row=3; row < height-3; row++)
+ for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
+ pix = image + row*width+col;
+ for (avg=i=0; i < 4; i++)
+ avg += gr[i] = pix[dir[i]][1] << 2;
+ avg >>= 2;
+ for (i=0; i < 8; i+=2)
+ if (gr[sort[i]] > gr[sort[i+1]])
+ SWAP(gr[sort[i]],gr[sort[i+1]])
+ for (d=0; d < 4; d++) {
+ for (i=-2; i < 2; i++)
+ if (pix[i*dir[d] + (i+1)*dir[d+1]][1] <= avg) break;
+ if (i == 2) {
+ pix[0][1] = (gr[1]+gr[2]) >> 3;
+ goto next_pixel;
+ }
+ }
+ for (i=0; (d=dir[i]) > 0; i++) {
+ guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
+ - pix[-2*d][c] - pix[2*d][c];
+ diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
+ ABS(pix[ 2*d][c] - pix[ 0][c]) +
+ ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
+ ( ABS(pix[ 3*d][1] - pix[ d][1]) +
+ ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
+ }
+ d = dir[i = diff[0] > diff[1]];
+ pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
+next_pixel: ;
+ }
+/* Calculate red and blue for each green pixel: */
+ for (row=1; row < height-1; row++)
+ for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
+ pix = image + row*width+col;
+ for (i=0; (d=dir[i]) > 0; c=2-c, i++)
+ pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
+ - pix[-d][1] - pix[d][1]) >> 1);
+ }
+/* Calculate blue for red pixels and vice versa: */
+ for (row=1; row < height-1; row++)
+ for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
+ pix = image + row*width+col;
+ for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
+ diff[i] = ABS(pix[-d][c] - pix[d][c]) +
+ ABS(pix[-d][1] - pix[0][1]) +
+ ABS(pix[ d][1] - pix[0][1]);
+ guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
+ - pix[-d][1] - pix[d][1];
+ }
+ if (diff[0] != diff[1])
+ pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
+ else
+ pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
+ }
+}
+
+/*
+ Adaptive Homogeneity-Directed interpolation is based on
+ the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
+ */
+#define TS 256 /* Tile Size */
+
+void CLASS ahd_interpolate()
+{
+ int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
+ ushort (*pix)[4], (*rix)[3];
+ static const int dir[4] = { -1, 1, -TS, TS };
+ unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
+ float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
+ ushort (*rgb)[TS][TS][3];
+ short (*lab)[TS][TS][3], (*lix)[3];
+ char (*homo)[TS][TS], *buffer;
+
+ if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
+
+ for (i=0; i < 0x10000; i++) {
+ r = i / 65535.0;
+ cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
+ }
+ for (i=0; i < 3; i++)
+ for (j=0; j < colors; j++)
+ for (xyz_cam[i][j] = k=0; k < 3; k++)
+ xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
+
+ border_interpolate(5);
+ buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
+ merror (buffer, "ahd_interpolate()");
+ rgb = (ushort(*)[TS][TS][3]) buffer;
+ lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
+ homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
+
+ for (top=2; top < height-5; top += TS-6)
+ for (left=2; left < width-5; left += TS-6) {
+
+/* Interpolate green horizontally and vertically: */
+ for (row = top; row < top+TS && row < height-2; row++) {
+ col = left + (FC(row,left) & 1);
+ for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
+ pix = image + row*width+col;
+ val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
+ - pix[-2][c] - pix[2][c]) >> 2;
+ rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
+ val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
+ - pix[-2*width][c] - pix[2*width][c]) >> 2;
+ rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
+ }
+ }
+/* Interpolate red and blue, and convert to CIELab: */
+ for (d=0; d < 2; d++)
+ for (row=top+1; row < top+TS-1 && row < height-3; row++)
+ for (col=left+1; col < left+TS-1 && col < width-3; col++) {
+ pix = image + row*width+col;
+ rix = &rgb[d][row-top][col-left];
+ lix = &lab[d][row-top][col-left];
+ if ((c = 2 - FC(row,col)) == 1) {
+ c = FC(row+1,col);
+ val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
+ - rix[-1][1] - rix[1][1] ) >> 1);
+ rix[0][2-c] = CLIP(val);
+ val = pix[0][1] + (( pix[-width][c] + pix[width][c]
+ - rix[-TS][1] - rix[TS][1] ) >> 1);
+ } else
+ val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
+ + pix[+width-1][c] + pix[+width+1][c]
+ - rix[-TS-1][1] - rix[-TS+1][1]
+ - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
+ rix[0][c] = CLIP(val);
+ c = FC(row,col);
+ rix[0][c] = pix[0][c];
+ xyz[0] = xyz[1] = xyz[2] = 0.5;
+ FORCC {
+ xyz[0] += xyz_cam[0][c] * rix[0][c];
+ xyz[1] += xyz_cam[1][c] * rix[0][c];
+ xyz[2] += xyz_cam[2][c] * rix[0][c];
+ }
+ xyz[0] = cbrt[CLIP((int) xyz[0])];
+ xyz[1] = cbrt[CLIP((int) xyz[1])];
+ xyz[2] = cbrt[CLIP((int) xyz[2])];
+ lix[0][0] = 64 * (116 * xyz[1] - 16);
+ lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
+ lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
+ }
+/* Build homogeneity maps from the CIELab images: */
+ memset (homo, 0, 2*TS*TS);
+ for (row=top+2; row < top+TS-2 && row < height-4; row++) {
+ tr = row-top;
+ for (col=left+2; col < left+TS-2 && col < width-4; col++) {
+ tc = col-left;
+ for (d=0; d < 2; d++) {
+ lix = &lab[d][tr][tc];
+ for (i=0; i < 4; i++) {
+ ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
+ abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
+ + SQR(lix[0][2]-lix[dir[i]][2]);
+ }
+ }
+ leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
+ MAX(ldiff[1][2],ldiff[1][3]));
+ abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
+ MAX(abdiff[1][2],abdiff[1][3]));
+ for (d=0; d < 2; d++)
+ for (i=0; i < 4; i++)
+ if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
+ homo[d][tr][tc]++;
+ }
+ }
+/* Combine the most homogenous pixels for the final result: */
+ for (row=top+3; row < top+TS-3 && row < height-5; row++) {
+ tr = row-top;
+ for (col=left+3; col < left+TS-3 && col < width-5; col++) {
+ tc = col-left;
+ for (d=0; d < 2; d++)
+ for (hm[d]=0, i=tr-1; i <= tr+1; i++)
+ for (j=tc-1; j <= tc+1; j++)
+ hm[d] += homo[d][i][j];
+ if (hm[0] != hm[1])
+ FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
+ else
+ FORC3 image[row*width+col][c] =
+ (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
+ }
+ }
+ }
+ free (buffer);
+}
+#undef TS
+
+void CLASS median_filter ()
+{
+ ushort (*pix)[4];
+ int pass, c, i, j, k, med[9];
+ static const uchar opt[] = /* Optimal 9-element median search */
+ { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
+ 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
+
+ for (pass=1; pass <= med_passes; pass++) {
+ if (verbose)
+ fprintf (stderr,_("Median filter pass %d...\n"), pass);
+ for (c=0; c < 3; c+=2) {
+ for (pix = image; pix < image+width*height; pix++)
+ pix[0][3] = pix[0][c];
+ for (pix = image+width; pix < image+width*(height-1); pix++) {
+ if ((pix-image+1) % width < 2) continue;
+ for (k=0, i = -width; i <= width; i += width)
+ for (j = i-1; j <= i+1; j++)
+ med[k++] = pix[j][3] - pix[j][1];
+ for (i=0; i < sizeof opt; i+=2)
+ if (med[opt[i]] > med[opt[i+1]])
+ SWAP (med[opt[i]] , med[opt[i+1]]);
+ pix[0][c] = CLIP(med[4] + pix[0][1]);
+ }
+ }
+ }
+}
+
+void CLASS blend_highlights()
+{
+ int clip=INT_MAX, row, col, c, i, j;
+ static const float trans[2][4][4] =
+ { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
+ { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
+ static const float itrans[2][4][4] =
+ { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
+ { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
+ float cam[2][4], lab[2][4], sum[2], chratio;
+
+ if ((unsigned) (colors-3) > 1) return;
+ if (verbose) fprintf (stderr,_("Blending highlights...\n"));
+ FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++) {
+ FORCC if (image[row*width+col][c] > clip) break;
+ if (c == colors) continue;
+ FORCC {
+ cam[0][c] = image[row*width+col][c];
+ cam[1][c] = MIN(cam[0][c],clip);
+ }
+ for (i=0; i < 2; i++) {
+ FORCC for (lab[i][c]=j=0; j < colors; j++)
+ lab[i][c] += trans[colors-3][c][j] * cam[i][j];
+ for (sum[i]=0,c=1; c < colors; c++)
+ sum[i] += SQR(lab[i][c]);
+ }
+ chratio = sqrt(sum[1]/sum[0]);
+ for (c=1; c < colors; c++)
+ lab[0][c] *= chratio;
+ FORCC for (cam[0][c]=j=0; j < colors; j++)
+ cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
+ FORCC image[row*width+col][c] = cam[0][c] / colors;
+ }
+}
+
+#define SCALE (4 >> shrink)
+void CLASS recover_highlights()
+{
+ float *map, sum, wgt, grow;
+ int hsat[4], count, spread, change, val, i;
+ unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
+ ushort *pixel;
+ static const signed char dir[8][2] =
+ { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
+
+ if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
+
+ grow = pow (2, 4-highlight);
+ FORCC hsat[c] = 32000 * pre_mul[c];
+ for (kc=0, c=1; c < colors; c++)
+ if (pre_mul[kc] < pre_mul[c]) kc = c;
+ high = height / SCALE;
+ wide = width / SCALE;
+ map = (float *) calloc (high*wide, sizeof *map);
+ merror (map, "recover_highlights()");
+ FORCC if (c != kc) {
+ memset (map, 0, high*wide*sizeof *map);
+ for (mrow=0; mrow < high; mrow++)
+ for (mcol=0; mcol < wide; mcol++) {
+ sum = wgt = count = 0;
+ for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
+ for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
+ pixel = image[row*width+col];
+ if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
+ sum += pixel[c];
+ wgt += pixel[kc];
+ count++;
+ }
+ }
+ if (count == SCALE*SCALE)
+ map[mrow*wide+mcol] = sum / wgt;
+ }
+ for (spread = 32/grow; spread--; ) {
+ for (mrow=0; mrow < high; mrow++)
+ for (mcol=0; mcol < wide; mcol++) {
+ if (map[mrow*wide+mcol]) continue;
+ sum = count = 0;
+ for (d=0; d < 8; d++) {
+ y = mrow + dir[d][0];
+ x = mcol + dir[d][1];
+ if (y < high && x < wide && map[y*wide+x] > 0) {
+ sum += (1 + (d & 1)) * map[y*wide+x];
+ count += 1 + (d & 1);
+ }
+ }
+ if (count > 3)
+ map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
+ }
+ for (change=i=0; i < high*wide; i++)
+ if (map[i] < 0) {
+ map[i] = -map[i];
+ change = 1;
+ }
+ if (!change) break;
+ }
+ for (i=0; i < high*wide; i++)
+ if (map[i] == 0) map[i] = 1;
+ for (mrow=0; mrow < high; mrow++)
+ for (mcol=0; mcol < wide; mcol++) {
+ for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
+ for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
+ pixel = image[row*width+col];
+ if (pixel[c] / hsat[c] > 1) {
+ val = pixel[kc] * map[mrow*wide+mcol];
+ if (pixel[c] < val) pixel[c] = CLIP(val);
+ }
+ }
+ }
+ }
+ free (map);
+}
+#undef SCALE
+
+void CLASS tiff_get (unsigned base,
+ unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
+{
+ *tag = get2();
+ *type = get2();
+ *len = get4();
+ *save = ftell(ifp) + 4;
+ if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
+ fseek (ifp, get4()+base, SEEK_SET);
+}
+
+void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
+{
+ unsigned entries, tag, type, len, save;
+
+ entries = get2();
+ while (entries--) {
+ tiff_get (base, &tag, &type, &len, &save);
+ if (tag == toff) thumb_offset = get4()+base;
+ if (tag == tlen) thumb_length = get4();
+ fseek (ifp, save, SEEK_SET);
+ }
+}
+
+int CLASS parse_tiff_ifd (int base);
+
+void CLASS parse_makernote (int base, int uptag)
+{
+ static const uchar xlat[2][256] = {
+ { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
+ 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
+ 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
+ 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
+ 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
+ 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
+ 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
+ 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
+ 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
+ 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
+ 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
+ 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
+ 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
+ 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
+ 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
+ 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
+ { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
+ 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
+ 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
+ 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
+ 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
+ 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
+ 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
+ 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
+ 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
+ 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
+ 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
+ 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
+ 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
+ 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
+ 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
+ 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
+ unsigned offset=0, entries, tag, type, len, save, c;
+ unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
+ uchar buf97[324], ci, cj, ck;
+ short sorder=order;
+ char buf[10];
+/*
+ The MakerNote might have its own TIFF header (possibly with
+ its own byte-order!), or it might just be a table.
+ */
+ fread (buf, 1, 10, ifp);
+ if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
+ !strncmp (buf,"VER" ,3) ||
+ !strncmp (buf,"IIII",4) ||
+ !strncmp (buf,"MMMM",4)) return;
+ if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
+ !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
+ order = 0x4d4d;
+ while ((i=ftell(ifp)) < data_offset && i < 16384) {
+ wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
+ wb[3] = get2();
+ if (wb[1] == 256 && wb[3] == 256 &&
+ wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
+ FORC4 cam_mul[c] = wb[c];
+ }
+ goto quit;
+ }
+ if (!strcmp (buf,"Nikon")) {
+ base = ftell(ifp);
+ order = get2();
+ if (get2() != 42) goto quit;
+ offset = get4();
+ fseek (ifp, offset-8, SEEK_CUR);
+ } else if (!strcmp (buf,"OLYMPUS")) {
+ base = ftell(ifp)-10;
+ fseek (ifp, -2, SEEK_CUR);
+ order = get2(); get2();
+ } else if (!strncmp (buf,"FUJIFILM",8) ||
+ !strncmp (buf,"SONY",4) ||
+ !strcmp (buf,"Panasonic")) {
+ order = 0x4949;
+ fseek (ifp, 2, SEEK_CUR);
+ } else if (!strcmp (buf,"OLYMP") ||
+ !strcmp (buf,"LEICA") ||
+ !strcmp (buf,"Ricoh") ||
+ !strcmp (buf,"EPSON"))
+ fseek (ifp, -2, SEEK_CUR);
+ else if (!strcmp (buf,"AOC") ||
+ !strcmp (buf,"QVC"))
+ fseek (ifp, -4, SEEK_CUR);
+ else fseek (ifp, -10, SEEK_CUR);
+
+ entries = get2();
+ if (entries > 1000) return;
+ while (entries--) {
+ tiff_get (base, &tag, &type, &len, &save);
+ tag |= uptag << 16;
+ if (tag == 2 && strstr(make,"NIKON"))
+ iso_speed = (get2(),get2());
+ if (tag == 4 && len > 26 && len < 35) {
+ iso_speed = 50 * pow (2, (get4(),get2())/32.0 - 4);
+ if ((i=(get2(),get2())) != 0x7fff)
+ aperture = pow (2, i/64.0);
+ if ((i=get2()) != 0xffff)
+ shutter = pow (2, (short) i/-32.0);
+ wbi = (get2(),get2());
+ shot_order = (get2(),get2());
+ }
+ if (tag == 8 && type == 4)
+ shot_order = get4();
+ if (tag == 9 && !strcmp(make,"Canon"))
+ fread (artist, 64, 1, ifp);
+ if (tag == 0xc && len == 4) {
+ cam_mul[0] = getrat();
+ cam_mul[2] = getrat();
+ }
+ if (tag == 0x10 && type == 4)
+ unique_id = get4();
+ if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
+ fseek (ifp, get4()+base, SEEK_SET);
+ parse_tiff_ifd (base);
+ }
+ if (tag == 0x14 && len == 2560 && type == 7) {
+ fseek (ifp, 1248, SEEK_CUR);
+ goto get2_256;
+ }
+ if (tag == 0x15 && type == 2 && is_raw)
+ fread (model, 64, 1, ifp);
+ if (strstr(make,"PENTAX")) {
+ if (tag == 0x1b) tag = 0x1018;
+ if (tag == 0x1c) tag = 0x1017;
+ }
+ if (tag == 0x1d)
+ while ((c = fgetc(ifp)) && c != EOF)
+ serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
+ if (tag == 0x81 && type == 4) {
+ data_offset = get4();
+ fseek (ifp, data_offset + 41, SEEK_SET);
+ raw_height = get2() * 2;
+ raw_width = get2();
+ filters = 0x61616161;
+ }
+ if (tag == 0x29 && type == 1) {
+ c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
+ fseek (ifp, 8 + c*32, SEEK_CUR);
+ FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
+ }
+ if ((tag == 0x81 && type == 7) ||
+ (tag == 0x100 && type == 7) ||
+ (tag == 0x280 && type == 1)) {
+ thumb_offset = ftell(ifp);
+ thumb_length = len;
+ }
+ if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
+ thumb_offset += base;
+ if (tag == 0x89 && type == 4)
+ thumb_length = get4();
+ if (tag == 0x8c || tag == 0x96)
+ meta_offset = ftell(ifp);
+ if (tag == 0x97) {
+ for (i=0; i < 4; i++)
+ ver97 = (ver97 << 4) + fgetc(ifp)-'0';
+ switch (ver97) {
+ case 0x100:
+ fseek (ifp, 68, SEEK_CUR);
+ FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
+ break;
+ case 0x102:
+ fseek (ifp, 6, SEEK_CUR);
+ goto get2_rggb;
+ case 0x103:
+ fseek (ifp, 16, SEEK_CUR);
+ FORC4 cam_mul[c] = get2();
+ }
+ if (ver97 >> 8 == 2) {
+ if (ver97 != 0x205) fseek (ifp, 280, SEEK_CUR);
+ fread (buf97, 324, 1, ifp);
+ }
+ }
+ if (tag == 0xa4 && type == 3) {
+ fseek (ifp, wbi*48, SEEK_CUR);
+ FORC3 cam_mul[c] = get2();
+ }
+ if (tag == 0xa7 && ver97 >> 8 == 2) {
+ ci = xlat[0][serial & 0xff];
+ cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
+ ck = 0x60;
+ for (i=0; i < 324; i++)
+ buf97[i] ^= (cj += ci * ck++);
+ FORC4 cam_mul[c ^ (c >> 1)] =
+ sget2 (buf97 + (ver97 == 0x205 ? 14:6) + c*2);
+ if (ver97 == 0x209)
+ FORC4 cam_mul[c ^ (c >> 1) ^ 1] =
+ sget2 (buf97 + 10 + c*2);
+ }
+ if (tag == 0x200 && len == 3)
+ shot_order = (get4(),get4());
+ if (tag == 0x200 && len == 4)
+ black = (get2()+get2()+get2()+get2())/4;
+ if (tag == 0x201 && len == 4)
+ goto get2_rggb;
+ if (tag == 0x401 && len == 4) {
+ black = (get4()+get4()+get4()+get4())/4;
+ }
+ if (tag == 0xe01) { /* Nikon Capture Note */
+ type = order;
+ order = 0x4949;
+ fseek (ifp, 22, SEEK_CUR);
+ for (offset=22; offset+22 < len; offset += 22+i) {
+ tag = get4();
+ fseek (ifp, 14, SEEK_CUR);
+ i = get4()-4;
+ if (tag == 0x76a43207) flip = get2();
+ else fseek (ifp, i, SEEK_CUR);
+ }
+ order = type;
+ }
+ if (tag == 0xe80 && len == 256 && type == 7) {
+ fseek (ifp, 48, SEEK_CUR);
+ cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
+ cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
+ }
+ if (tag == 0xf00 && type == 7) {
+ if (len == 614)
+ fseek (ifp, 176, SEEK_CUR);
+ else if (len == 734 || len == 1502)
+ fseek (ifp, 148, SEEK_CUR);
+ else goto next;
+ goto get2_256;
+ }
+ if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
+ for (i=0; i < 3; i++)
+ FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
+ if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
+ for (black = i=0; i < 4; i++)
+ black += get2() << 2;
+ if (tag == 0x1017 || tag == 0x20400100)
+ cam_mul[0] = get2() / 256.0;
+ if (tag == 0x1018 || tag == 0x20400100)
+ cam_mul[2] = get2() / 256.0;
+ if (tag == 0x2011 && len == 2) {
+get2_256:
+ order = 0x4d4d;
+ cam_mul[0] = get2() / 256.0;
+ cam_mul[2] = get2() / 256.0;
+ }
+ if (tag == 0x2020)
+ parse_thumb_note (base, 257, 258);
+ if (tag == 0x2040)
+ parse_makernote (base, 0x2040);
+ if (tag == 0xb028) {
+ fseek (ifp, get4(), SEEK_SET);
+ parse_thumb_note (base, 136, 137);
+ }
+ if (tag == 0x4001 && type == 3) {
+ i = len == 582 ? 50 : len == 653 ? 68 : 126;
+ fseek (ifp, i, SEEK_CUR);
+get2_rggb:
+ FORC4 cam_mul[c ^ (c >> 1)] = get2();
+ fseek (ifp, 22, SEEK_CUR);
+ FORC4 sraw_mul[c ^ (c >> 1)] = get2();
+ }
+next:
+ fseek (ifp, save, SEEK_SET);
+ }
+quit:
+ order = sorder;
+}
+
+/*
+ Since the TIFF DateTime string has no timezone information,
+ assume that the camera's clock was set to Universal Time.
+ */
+void CLASS get_timestamp (int reversed)
+{
+ struct tm t;
+ char str[20];
+ int i;
+
+ str[19] = 0;
+ if (reversed)
+ for (i=19; i--; ) str[i] = fgetc(ifp);
+ else
+ fread (str, 19, 1, ifp);
+ memset (&t, 0, sizeof t);
+ if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
+ &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
+ return;
+ t.tm_year -= 1900;
+ t.tm_mon -= 1;
+ if (mktime(&t) > 0)
+ timestamp = mktime(&t);
+}
+
+void CLASS parse_exif (int base)
+{
+ unsigned kodak, entries, tag, type, len, save, c;
+ double expo;
+
+ kodak = !strncmp(make,"EASTMAN",7);
+ entries = get2();
+ while (entries--) {
+ tiff_get (base, &tag, &type, &len, &save);
+ switch (tag) {
+ case 33434: shutter = getrat(); break;
+ case 33437: aperture = getrat(); break;
+ case 34855: iso_speed = get2(); break;
+ case 36867:
+ case 36868: get_timestamp(0); break;
+ case 37377: if ((expo = -getrat()) < 128)
+ shutter = pow (2, expo); break;
+ case 37378: aperture = pow (2, getrat()/2); break;
+ case 37386: focal_len = getrat(); break;
+ case 37500: parse_makernote (base, 0); break;
+ case 40962: if (kodak) raw_width = get4(); break;
+ case 40963: if (kodak) raw_height = get4(); break;
+ case 41730:
+ if (get4() == 0x20002)
+ for (exif_cfa=c=0; c < 8; c+=2)
+ exif_cfa |= fgetc(ifp) * 0x01010101 << c;
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+}
+
+void CLASS romm_coeff (float romm_cam[3][3])
+{
+ static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
+ { { 2.034193, -0.727420, -0.306766 },
+ { -0.228811, 1.231729, -0.002922 },
+ { -0.008565, -0.153273, 1.161839 } };
+ int i, j, k;
+
+ for (i=0; i < 3; i++)
+ for (j=0; j < 3; j++)
+ for (cmatrix[i][j] = k=0; k < 3; k++)
+ cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
+}
+
+void CLASS parse_mos (int offset)
+{
+ char data[40];
+ int skip, from, i, c, neut[4], planes=0, frot=0;
+ static const char *mod[] =
+ { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
+ "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
+ "Aptus 54S","Aptus 65S","Aptus 75S" };
+ float romm_cam[3][3];
+
+ fseek (ifp, offset, SEEK_SET);
+ while (1) {
+ if (get4() != 0x504b5453) break;
+ get4();
+ fread (data, 1, 40, ifp);
+ skip = get4();
+ from = ftell(ifp);
+ if (!strcmp(data,"JPEG_preview_data")) {
+ thumb_offset = from;
+ thumb_length = skip;
+ }
+ if (!strcmp(data,"icc_camera_profile")) {
+ profile_offset = from;
+ profile_length = skip;
+ }
+ if (!strcmp(data,"ShootObj_back_type")) {
+ fscanf (ifp, "%d", &i);
+ if ((unsigned) i < sizeof mod / sizeof (*mod))
+ strcpy (model, mod[i]);
+ }
+ if (!strcmp(data,"icc_camera_to_tone_matrix")) {
+ for (i=0; i < 9; i++)
+ romm_cam[0][i] = int_to_float(get4());
+ romm_coeff (romm_cam);
+ }
+ if (!strcmp(data,"CaptProf_color_matrix")) {
+ for (i=0; i < 9; i++)
+ fscanf (ifp, "%f", &romm_cam[0][i]);
+ romm_coeff (romm_cam);
+ }
+ if (!strcmp(data,"CaptProf_number_of_planes"))
+ fscanf (ifp, "%d", &planes);
+ if (!strcmp(data,"CaptProf_raw_data_rotation"))
+ fscanf (ifp, "%d", &flip);
+ if (!strcmp(data,"CaptProf_mosaic_pattern"))
+ FORC4 {
+ fscanf (ifp, "%d", &i);
+ if (i == 1) frot = c ^ (c >> 1);
+ }
+ if (!strcmp(data,"ImgProf_rotation_angle")) {
+ fscanf (ifp, "%d", &i);
+ flip = i - flip;
+ }
+ if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
+ FORC4 fscanf (ifp, "%d", neut+c);
+ FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
+ }
+ parse_mos (from);
+ fseek (ifp, skip+from, SEEK_SET);
+ }
+ if (planes)
+ filters = (planes == 1) * 0x01010101 *
+ (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
+}
+
+void CLASS linear_table (unsigned len)
+{
+ int i;
+ if (len > 0x1000) len = 0x1000;
+ read_shorts (curve, len);
+ for (i=len; i < 0x1000; i++)
+ curve[i] = curve[i-1];
+ maximum = curve[0xfff];
+}
+
+void CLASS parse_kodak_ifd (int base)
+{
+ unsigned entries, tag, type, len, save;
+ int i, c, wbi=-2, wbtemp=6500;
+ float mul[3], num;
+
+ entries = get2();
+ if (entries > 1024) return;
+ while (entries--) {
+ tiff_get (base, &tag, &type, &len, &save);
+ if (tag == 1020) wbi = getint(type);
+ if (tag == 1021 && len == 72) { /* WB set in software */
+ fseek (ifp, 40, SEEK_CUR);
+ FORC3 cam_mul[c] = 2048.0 / get2();
+ wbi = -2;
+ }
+ if (tag == 2118) wbtemp = getint(type);
+ if (tag == 2130 + wbi)
+ FORC3 mul[c] = getreal(type);
+ if (tag == 2140 + wbi && wbi >= 0)
+ FORC3 {
+ for (num=i=0; i < 4; i++)
+ num += getreal(type) * pow (wbtemp/100.0, i);
+ cam_mul[c] = 2048 / (num * mul[c]);
+ }
+ if (tag == 2317) linear_table (len);
+ if (tag == 6020) iso_speed = getint(type);
+ fseek (ifp, save, SEEK_SET);
+ }
+}
+
+void CLASS parse_minolta (int base);
+
+int CLASS parse_tiff_ifd (int base)
+{
+ unsigned entries, tag, type, len, plen=16, save;
+ int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
+ char software[64], *cbuf, *cp;
+ uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
+ double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num;
+ double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
+ unsigned sony_curve[] = { 0,0,0,0,0,4095 };
+ unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
+ struct jhead jh;
+ FILE *sfp;
+
+ if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
+ return 1;
+ ifd = tiff_nifds++;
+ for (j=0; j < 4; j++)
+ for (i=0; i < 4; i++)
+ cc[j][i] = i == j;
+ entries = get2();
+ if (entries > 512) return 1;
+ while (entries--) {
+ tiff_get (base, &tag, &type, &len, &save);
+ switch (tag) {
+ case 17: case 18:
+ if (type == 3 && len == 1)
+ cam_mul[(tag-17)*2] = get2() / 256.0;
+ break;
+ case 23:
+ if (type == 3) iso_speed = get2();
+ break;
+ case 36: case 37: case 38:
+ cam_mul[tag-0x24] = get2();
+ break;
+ case 39:
+ if (len < 50 || cam_mul[0]) break;
+ fseek (ifp, 12, SEEK_CUR);
+ FORC3 cam_mul[c] = get2();
+ break;
+ case 46:
+ if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
+ thumb_offset = ftell(ifp) - 2;
+ thumb_length = len;
+ break;
+ case 2: case 256: /* ImageWidth */
+ tiff_ifd[ifd].width = getint(type);
+ break;
+ case 3: case 257: /* ImageHeight */
+ tiff_ifd[ifd].height = getint(type);
+ break;
+ case 258: /* BitsPerSample */
+ tiff_ifd[ifd].samples = len & 7;
+ tiff_ifd[ifd].bps = get2();
+ break;
+ case 259: /* Compression */
+ tiff_ifd[ifd].comp = get2();
+ break;
+ case 262: /* PhotometricInterpretation */
+ tiff_ifd[ifd].phint = get2();
+ break;
+ case 270: /* ImageDescription */
+ fread (desc, 512, 1, ifp);
+ break;
+ case 271: /* Make */
+ fgets (make, 64, ifp);
+ break;
+ case 272: /* Model */
+ fgets (model, 64, ifp);
+ break;
+ case 273: /* StripOffset */
+ case 513:
+ tiff_ifd[ifd].offset = get4()+base;
+ if (!tiff_ifd[ifd].bps) {
+ fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
+ if (ljpeg_start (&jh, 1)) {
+ tiff_ifd[ifd].comp = 6;
+ tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2);
+ tiff_ifd[ifd].height = jh.high;
+ tiff_ifd[ifd].bps = jh.bits;
+ tiff_ifd[ifd].samples = jh.clrs;
+ }
+ }
+ break;
+ case 274: /* Orientation */
+ tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
+ break;
+ case 277: /* SamplesPerPixel */
+ tiff_ifd[ifd].samples = getint(type) & 7;
+ break;
+ case 279: /* StripByteCounts */
+ case 514:
+ tiff_ifd[ifd].bytes = get4();
+ break;
+ case 305: /* Software */
+ fgets (software, 64, ifp);
+ if (!strncmp(software,"Adobe",5) ||
+ !strncmp(software,"dcraw",5) ||
+ !strncmp(software,"Bibble",6) ||
+ !strncmp(software,"Nikon Scan",10) ||
+ !strcmp (software,"Digital Photo Professional"))
+ is_raw = 0;
+ break;
+ case 306: /* DateTime */
+ get_timestamp(0);
+ break;
+ case 315: /* Artist */
+ fread (artist, 64, 1, ifp);
+ break;
+ case 322: /* TileWidth */
+ tile_width = getint(type);
+ break;
+ case 323: /* TileLength */
+ tile_length = getint(type);
+ break;
+ case 324: /* TileOffsets */
+ tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
+ if (len == 4) {
+ load_raw = &CLASS sinar_4shot_load_raw;
+ is_raw = 5;
+ }
+ break;
+ case 330: /* SubIFDs */
+ if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
+ data_offset = get4()+base;
+ ifd++; break;
+ }
+ while (len--) {
+ i = ftell(ifp);
+ fseek (ifp, get4()+base, SEEK_SET);
+ if (parse_tiff_ifd (base)) break;
+ fseek (ifp, i+4, SEEK_SET);
+ }
+ break;
+ case 400:
+ strcpy (make, "Sarnoff");
+ maximum = 0xfff;
+ break;
+ case 28688:
+ FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
+ for (i=0; i < 5; i++)
+ for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
+ curve[j] = curve[j-1] + (1 << i);
+ break;
+ case 29184: sony_offset = get4(); break;
+ case 29185: sony_length = get4(); break;
+ case 29217: sony_key = get4(); break;
+ case 29264:
+ parse_minolta (ftell(ifp));
+ raw_width = 0;
+ break;
+ case 29443:
+ FORC4 cam_mul[c ^ (c < 2)] = get2();
+ break;
+ case 33405: /* Model2 */
+ fgets (model2, 64, ifp);
+ break;
+ case 33422: /* CFAPattern */
+ case 64777: /* Kodak P-series */
+ if ((plen=len) > 16) plen = 16;
+ fread (cfa_pat, 1, plen, ifp);
+ for (colors=cfa=i=0; i < plen; i++) {
+ colors += !(cfa & (1 << cfa_pat[i]));
+ cfa |= 1 << cfa_pat[i];
+ }
+ if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
+ if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
+ goto guess_cfa_pc;
+ case 33424:
+ fseek (ifp, get4()+base, SEEK_SET);
+ parse_kodak_ifd (base);
+ break;
+ case 33434: /* ExposureTime */
+ shutter = getrat();
+ break;
+ case 33437: /* FNumber */
+ aperture = getrat();
+ break;
+ case 34306: /* Leaf white balance */
+ FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
+ break;
+ case 34307: /* Leaf CatchLight color matrix */
+ fread (software, 1, 7, ifp);
+ if (strncmp(software,"MATRIX",6)) break;
+ colors = 4;
+ for (raw_color = i=0; i < 3; i++) {
+ FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
+ if (!use_camera_wb) continue;
+ num = 0;
+ FORC4 num += rgb_cam[i][c];
+ FORC4 rgb_cam[i][c] /= num;
+ }
+ break;
+ case 34310: /* Leaf metadata */
+ parse_mos (ftell(ifp));
+ case 34303:
+ strcpy (make, "Leaf");
+ break;
+ case 34665: /* EXIF tag */
+ fseek (ifp, get4()+base, SEEK_SET);
+ parse_exif (base);
+ break;
+ case 34675: /* InterColorProfile */
+ case 50831: /* AsShotICCProfile */
+ profile_offset = ftell(ifp);
+ profile_length = len;
+ break;
+ case 37122: /* CompressedBitsPerPixel */
+ kodak_cbpp = get4();
+ break;
+ case 37386: /* FocalLength */
+ focal_len = getrat();
+ break;
+ case 37393: /* ImageNumber */
+ shot_order = getint(type);
+ break;
+ case 37400: /* old Kodak KDC tag */
+ for (raw_color = i=0; i < 3; i++) {
+ getrat();
+ FORC3 rgb_cam[i][c] = getrat();
+ }
+ break;
+ case 46275: /* Imacon tags */
+ strcpy (make, "Imacon");
+ data_offset = ftell(ifp);
+ ima_len = len;
+ break;
+ case 46279:
+ fseek (ifp, 78, SEEK_CUR);
+ raw_width = get4();
+ raw_height = get4();
+ left_margin = get4() & 7;
+ width = raw_width - left_margin - (get4() & 7);
+ top_margin = get4() & 7;
+ height = raw_height - top_margin - (get4() & 7);
+ if (raw_width == 7262) {
+ height = 5444;
+ width = 7244;
+ left_margin = 7;
+ }
+ fseek (ifp, 52, SEEK_CUR);
+ FORC3 cam_mul[c] = getreal(11);
+ fseek (ifp, 114, SEEK_CUR);
+ flip = (get2() >> 7) * 90;
+ if (width * height * 6 == ima_len) {
+ if (flip % 180 == 90) SWAP(width,height);
+ filters = flip = 0;
+ }
+ sprintf (model, "Ixpress %d-Mp", height*width/1000000);
+ load_raw = &CLASS imacon_full_load_raw;
+ if (filters) {
+ if (left_margin & 1) filters = 0x61616161;
+ load_raw = &CLASS unpacked_load_raw;
+ }
+ maximum = 0xffff;
+ break;
+ case 50454: /* Sinar tag */
+ case 50455:
+ if (!(cbuf = (char *) malloc(len))) break;
+ fread (cbuf, 1, len, ifp);
+ for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
+ if (!strncmp (++cp,"Neutral ",8))
+ sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
+ free (cbuf);
+ break;
+ case 50459: /* Hasselblad tag */
+ i = order;
+ j = ftell(ifp);
+ c = tiff_nifds;
+ order = get2();
+ fseek (ifp, j+(get2(),get4()), SEEK_SET);
+ parse_tiff_ifd (j);
+ maximum = 0xffff;
+ tiff_nifds = c;
+ order = i;
+ break;
+ case 50706: /* DNGVersion */
+ FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
+ break;
+ case 50710: /* CFAPlaneColor */
+ if (len > 4) len = 4;
+ colors = len;
+ fread (cfa_pc, 1, colors, ifp);
+guess_cfa_pc:
+ FORCC tab[cfa_pc[c]] = c;
+ cdesc[c] = 0;
+ for (i=16; i--; )
+ filters = filters << 2 | tab[cfa_pat[i % plen]];
+ break;
+ case 50711: /* CFALayout */
+ if (get2() == 2) {
+ fuji_width = 1;
+ filters = 0x49494949;
+ }
+ break;
+ case 291:
+ case 50712: /* LinearizationTable */
+ linear_table (len);
+ break;
+ case 50714: /* BlackLevel */
+ case 50715: /* BlackLevelDeltaH */
+ case 50716: /* BlackLevelDeltaV */
+ for (dblack=i=0; i < len; i++)
+ dblack += getreal(type);
+ black += dblack/len + 0.5;
+ break;
+ case 50717: /* WhiteLevel */
+ maximum = getint(type);
+ break;
+ case 50718: /* DefaultScale */
+ pixel_aspect = getrat();
+ pixel_aspect /= getrat();
+ break;
+ case 50721: /* ColorMatrix1 */
+ case 50722: /* ColorMatrix2 */
+ FORCC for (j=0; j < 3; j++)
+ cm[c][j] = getrat();
+ use_cm = 1;
+ break;
+ case 50723: /* CameraCalibration1 */
+ case 50724: /* CameraCalibration2 */
+ for (i=0; i < colors; i++)
+ FORCC cc[i][c] = getrat();
+ case 50727: /* AnalogBalance */
+ FORCC ab[c] = getrat();
+ break;
+ case 50728: /* AsShotNeutral */
+ FORCC asn[c] = getreal(type);
+ break;
+ case 50729: /* AsShotWhiteXY */
+ xyz[0] = getrat();
+ xyz[1] = getrat();
+ xyz[2] = 1 - xyz[0] - xyz[1];
+ FORC3 xyz[c] /= d65_white[c];
+ break;
+ case 50740: /* DNGPrivateData */
+ if (dng_version) break;
+ parse_minolta (j = get4()+base);
+ fseek (ifp, j, SEEK_SET);
+ parse_tiff_ifd (base);
+ break;
+ case 50752:
+ read_shorts (cr2_slice, 3);
+ break;
+ case 50829: /* ActiveArea */
+ top_margin = getint(type);
+ left_margin = getint(type);
+ height = getint(type) - top_margin;
+ width = getint(type) - left_margin;
+ break;
+ case 64772: /* Kodak P-series */
+ fseek (ifp, 16, SEEK_CUR);
+ data_offset = get4();
+ fseek (ifp, 28, SEEK_CUR);
+ data_offset += get4();
+ load_raw = &CLASS packed_12_load_raw;
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+ if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
+ fseek (ifp, sony_offset, SEEK_SET);
+ fread (buf, sony_length, 1, ifp);
+ sony_decrypt (buf, sony_length/4, 1, sony_key);
+ sfp = ifp;
+ if ((ifp = tmpfile())) {
+ fwrite (buf, sony_length, 1, ifp);
+ fseek (ifp, 0, SEEK_SET);
+ parse_tiff_ifd (-sony_offset);
+ fclose (ifp);
+ }
+ ifp = sfp;
+ free (buf);
+ }
+ for (i=0; i < colors; i++)
+ FORCC cc[i][c] *= ab[i];
+ if (use_cm) {
+ FORCC for (i=0; i < 3; i++)
+ for (cam_xyz[c][i]=j=0; j < colors; j++)
+ cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
+ cam_xyz_coeff (cam_xyz);
+ }
+ if (asn[0]) {
+ cam_mul[3] = 0;
+ FORCC cam_mul[c] = 1 / asn[c];
+ }
+ if (!use_cm)
+ FORCC pre_mul[c] /= cc[c][c];
+ return 0;
+}
+
+void CLASS parse_tiff (int base)
+{
+ int doff, max_samp=0, raw=-1, thm=-1, i;
+ struct jhead jh;
+
+ fseek (ifp, base, SEEK_SET);
+ order = get2();
+ if (order != 0x4949 && order != 0x4d4d) return;
+ get2();
+ memset (tiff_ifd, 0, sizeof tiff_ifd);
+ tiff_nifds = 0;
+ while ((doff = get4())) {
+ fseek (ifp, doff+base, SEEK_SET);
+ if (parse_tiff_ifd (base)) break;
+ }
+ thumb_misc = 16;
+ if (thumb_offset) {
+ fseek (ifp, thumb_offset, SEEK_SET);
+ if (ljpeg_start (&jh, 1)) {
+ thumb_misc = jh.bits;
+ thumb_width = jh.wide;
+ thumb_height = jh.high;
+ }
+ }
+ for (i=0; i < tiff_nifds; i++) {
+ if (max_samp < tiff_ifd[i].samples)
+ max_samp = tiff_ifd[i].samples;
+ if (max_samp > 3) max_samp = 3;
+ if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
+ tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
+ raw_width = tiff_ifd[i].width;
+ raw_height = tiff_ifd[i].height;
+ tiff_bps = tiff_ifd[i].bps;
+ tiff_compress = tiff_ifd[i].comp;
+ data_offset = tiff_ifd[i].offset;
+ tiff_flip = tiff_ifd[i].flip;
+ tiff_samples = tiff_ifd[i].samples;
+ raw = i;
+ }
+ }
+ fuji_width *= (raw_width+1)/2;
+ if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip;
+ if (raw >= 0 && !load_raw)
+ switch (tiff_compress) {
+ case 0: case 1:
+ switch (tiff_bps) {
+ case 8: load_raw = &CLASS eight_bit_load_raw; break;
+ case 12: load_raw = &CLASS packed_12_load_raw;
+ if (!strncmp(make,"NIKON",5))
+ load_raw = &CLASS nikon_load_raw;
+ if (strncmp(make,"PENTAX",6)) break;
+ case 14:
+ case 16: load_raw = &CLASS unpacked_load_raw; break;
+ }
+ if (tiff_ifd[raw].bytes * 5 == raw_width * raw_height * 8)
+ load_raw = &CLASS olympus_e300_load_raw;
+ if (tiff_bps == 12 && tiff_ifd[raw].phint == 2)
+ load_raw = &CLASS olympus_cseries_load_raw;
+ break;
+ case 6: case 7: case 99:
+ load_raw = &CLASS lossless_jpeg_load_raw; break;
+ case 262:
+ load_raw = &CLASS kodak_262_load_raw; break;
+ case 32767:
+ load_raw = &CLASS sony_arw2_load_raw; break;
+ case 32769:
+ load_raw = &CLASS nikon_load_raw; break;
+ case 32773:
+ load_raw = &CLASS packed_12_load_raw; break;
+ case 34713:
+ load_raw = &CLASS nikon_compressed_load_raw; break;
+ case 65535:
+ load_raw = &CLASS pentax_k10_load_raw; break;
+ case 65000:
+ switch (tiff_ifd[raw].phint) {
+ case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
+ case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
+ case 32803: load_raw = &CLASS kodak_65000_load_raw;
+ }
+ case 32867: break;
+ default: is_raw = 0;
+ }
+ if (!dng_version && tiff_samples == 3)
+ if (tiff_ifd[raw].bytes && tiff_bps != 14 && tiff_bps != 2048)
+ is_raw = 0;
+ if (!dng_version && tiff_bps == 8 && tiff_compress == 1 &&
+ tiff_ifd[raw].phint == 1) is_raw = 0;
+ for (i=0; i < tiff_nifds; i++)
+ if (i != raw && tiff_ifd[i].samples == max_samp &&
+ tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
+ thumb_width * thumb_height / SQR(thumb_misc+1)) {
+ thumb_width = tiff_ifd[i].width;
+ thumb_height = tiff_ifd[i].height;
+ thumb_offset = tiff_ifd[i].offset;
+ thumb_length = tiff_ifd[i].bytes;
+ thumb_misc = tiff_ifd[i].bps;
+ thm = i;
+ }
+ if (thm >= 0) {
+ thumb_misc |= tiff_ifd[thm].samples << 5;
+ switch (tiff_ifd[thm].comp) {
+ case 0:
+ write_thumb = &CLASS layer_thumb;
+ break;
+ case 1:
+ if (tiff_ifd[thm].bps > 8)
+ thumb_load_raw = &CLASS kodak_thumb_load_raw;
+ else
+ write_thumb = &CLASS ppm_thumb;
+ break;
+ case 65000:
+ thumb_load_raw = tiff_ifd[thm].phint == 6 ?
+ &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
+ }
+ }
+}
+
+void CLASS parse_minolta (int base)
+{
+ int save, tag, len, offset, high=0, wide=0, i, c;
+ short sorder=order;
+
+ fseek (ifp, base, SEEK_SET);
+ if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
+ order = fgetc(ifp) * 0x101;
+ offset = base + get4() + 8;
+ while ((save=ftell(ifp)) < offset) {
+ for (tag=i=0; i < 4; i++)
+ tag = tag << 8 | fgetc(ifp);
+ len = get4();
+ switch (tag) {
+ case 0x505244: /* PRD */
+ fseek (ifp, 8, SEEK_CUR);
+ high = get2();
+ wide = get2();
+ break;
+ case 0x574247: /* WBG */
+ get4();
+ i = strstr(model,"A200") ? 3:0;
+ FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
+ break;
+ case 0x545457: /* TTW */
+ parse_tiff (ftell(ifp));
+ data_offset = offset;
+ }
+ fseek (ifp, save+len+8, SEEK_SET);
+ }
+ raw_height = high;
+ raw_width = wide;
+ order = sorder;
+}
+
+/*
+ Many cameras have a "debug mode" that writes JPEG and raw
+ at the same time. The raw file has no header, so try to
+ to open the matching JPEG file and read its metadata.
+ */
+void CLASS parse_external_jpeg()
+{
+ char *file, *ext, *jname, *jfile, *jext;
+ FILE *save=ifp;
+
+ ext = strrchr (ifname, '.');
+ file = strrchr (ifname, '/');
+ if (!file) file = strrchr (ifname, '\\');
+ if (!file) file = ifname-1;
+ file++;
+ if (!ext || strlen(ext) != 4 || ext-file != 8) return;
+ jname = (char *) malloc (strlen(ifname) + 1);
+ merror (jname, "parse_external()");
+ strcpy (jname, ifname);
+ jfile = file - ifname + jname;
+ jext = ext - ifname + jname;
+ if (strcasecmp (ext, ".jpg")) {
+ strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
+ memcpy (jfile, file+4, 4);
+ memcpy (jfile+4, file, 4);
+ } else
+ while (isdigit(*--jext)) {
+ if (*jext != '9') {
+ (*jext)++;
+ break;
+ }
+ *jext = '0';
+ }
+ if (strcmp (jname, ifname)) {
+ if ((ifp = fopen (jname, "rb"))) {
+ if (verbose)
+ fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
+ parse_tiff (12);
+ thumb_offset = 0;
+ is_raw = 1;
+ fclose (ifp);
+ }
+ }
+ if (!timestamp)
+ fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
+ free (jname);
+ ifp = save;
+}
+
+/*
+ CIFF block 0x1030 contains an 8x8 white sample.
+ Load this into white[][] for use in scale_colors().
+ */
+void CLASS ciff_block_1030()
+{
+ static const ushort key[] = { 0x410, 0x45f3 };
+ int i, bpp, row, col, vbits=0;
+ unsigned long bitbuf=0;
+
+ if ((get2(),get4()) != 0x80008 || !get4()) return;
+ bpp = get2();
+ if (bpp != 10 && bpp != 12) return;
+ for (i=row=0; row < 8; row++)
+ for (col=0; col < 8; col++) {
+ if (vbits < bpp) {
+ bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
+ vbits += 16;
+ }
+ white[row][col] =
+ bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp);
+ vbits -= bpp;
+ }
+}
+
+/*
+ Parse a CIFF file, better known as Canon CRW format.
+ */
+void CLASS parse_ciff (int offset, int length)
+{
+ int tboff, nrecs, c, type, len, save, wbi=-1;
+ ushort key[] = { 0x410, 0x45f3 };
+
+ fseek (ifp, offset+length-4, SEEK_SET);
+ tboff = get4() + offset;
+ fseek (ifp, tboff, SEEK_SET);
+ nrecs = get2();
+ if (nrecs > 100) return;
+ while (nrecs--) {
+ type = get2();
+ len = get4();
+ save = ftell(ifp) + 4;
+ fseek (ifp, offset+get4(), SEEK_SET);
+ if ((((type >> 8) + 8) | 8) == 0x38)
+ parse_ciff (ftell(ifp), len); /* Parse a sub-table */
+
+ if (type == 0x0810)
+ fread (artist, 64, 1, ifp);
+ if (type == 0x080a) {
+ fread (make, 64, 1, ifp);
+ fseek (ifp, strlen(make) - 63, SEEK_CUR);
+ fread (model, 64, 1, ifp);
+ }
+ if (type == 0x1810) {
+ fseek (ifp, 12, SEEK_CUR);
+ flip = get4();
+ }
+ if (type == 0x1835) /* Get the decoder table */
+ tiff_compress = get4();
+ if (type == 0x2007) {
+ thumb_offset = ftell(ifp);
+ thumb_length = len;
+ }
+ if (type == 0x1818) {
+ shutter = pow (2, -int_to_float((get4(),get4())));
+ aperture = pow (2, int_to_float(get4())/2);
+ }
+ if (type == 0x102a) {
+ iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
+ aperture = pow (2, (get2(),(short)get2())/64.0);
+ shutter = pow (2,-((short)get2())/32.0);
+ wbi = (get2(),get2());
+ if (wbi > 17) wbi = 0;
+ fseek (ifp, 32, SEEK_CUR);
+ if (shutter > 1e6) shutter = get2()/10.0;
+ }
+ if (type == 0x102c) {
+ if (get2() > 512) { /* Pro90, G1 */
+ fseek (ifp, 118, SEEK_CUR);
+ FORC4 cam_mul[c ^ 2] = get2();
+ } else { /* G2, S30, S40 */
+ fseek (ifp, 98, SEEK_CUR);
+ FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
+ }
+ }
+ if (type == 0x0032) {
+ if (len == 768) { /* EOS D30 */
+ fseek (ifp, 72, SEEK_CUR);
+ FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
+ if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
+ } else if (!cam_mul[0]) {
+ if (get2() == key[0]) /* Pro1, G6, S60, S70 */
+ c = (strstr(model,"Pro1") ?
+ "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
+ else { /* G3, G5, S45, S50 */
+ c = "023457000000006000"[wbi]-'0';
+ key[0] = key[1] = 0;
+ }
+ fseek (ifp, 78 + c*8, SEEK_CUR);
+ FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
+ if (!wbi) cam_mul[0] = -1;
+ }
+ }
+ if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
+ if (len > 66) wbi = "0134567028"[wbi]-'0';
+ fseek (ifp, 2 + wbi*8, SEEK_CUR);
+ FORC4 cam_mul[c ^ (c >> 1)] = get2();
+ }
+ if (type == 0x1030 && (0x18040 >> wbi & 1))
+ ciff_block_1030(); /* all that don't have 0x10a9 */
+ if (type == 0x1031) {
+ raw_width = (get2(),get2());
+ raw_height = get2();
+ }
+ if (type == 0x5029) {
+ focal_len = len >> 16;
+ if ((len & 0xffff) == 2) focal_len /= 32;
+ }
+ if (type == 0x5813) flash_used = int_to_float(len);
+ if (type == 0x5814) canon_ev = int_to_float(len);
+ if (type == 0x5817) shot_order = len;
+ if (type == 0x5834) unique_id = len;
+ if (type == 0x580e) timestamp = len;
+ if (type == 0x180e) timestamp = get4();
+#ifdef LOCALTIME
+ if ((type | 0x4000) == 0x580e)
+ timestamp = mktime (gmtime (&timestamp));
+#endif
+ fseek (ifp, save, SEEK_SET);
+ }
+}
+
+void CLASS parse_rollei()
+{
+ char line[128], *val;
+ struct tm t;
+
+ fseek (ifp, 0, SEEK_SET);
+ memset (&t, 0, sizeof t);
+ do {
+ fgets (line, 128, ifp);
+ if ((val = strchr(line,'=')))
+ *val++ = 0;
+ else
+ val = line + strlen(line);
+ if (!strcmp(line,"DAT"))
+ sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
+ if (!strcmp(line,"TIM"))
+ sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
+ if (!strcmp(line,"HDR"))
+ thumb_offset = atoi(val);
+ if (!strcmp(line,"X "))
+ raw_width = atoi(val);
+ if (!strcmp(line,"Y "))
+ raw_height = atoi(val);
+ if (!strcmp(line,"TX "))
+ thumb_width = atoi(val);
+ if (!strcmp(line,"TY "))
+ thumb_height = atoi(val);
+ } while (strncmp(line,"EOHD",4));
+ data_offset = thumb_offset + thumb_width * thumb_height * 2;
+ t.tm_year -= 1900;
+ t.tm_mon -= 1;
+ if (mktime(&t) > 0)
+ timestamp = mktime(&t);
+ strcpy (make, "Rollei");
+ strcpy (model,"d530flex");
+ write_thumb = &CLASS rollei_thumb;
+}
+
+void CLASS parse_sinar_ia()
+{
+ int entries, off;
+ char str[8], *cp;
+
+ order = 0x4949;
+ fseek (ifp, 4, SEEK_SET);
+ entries = get4();
+ fseek (ifp, get4(), SEEK_SET);
+ while (entries--) {
+ off = get4(); get4();
+ fread (str, 8, 1, ifp);
+ if (!strcmp(str,"META")) meta_offset = off;
+ if (!strcmp(str,"THUMB")) thumb_offset = off;
+ if (!strcmp(str,"RAW0")) data_offset = off;
+ }
+ fseek (ifp, meta_offset+20, SEEK_SET);
+ fread (make, 64, 1, ifp);
+ make[63] = 0;
+ if ((cp = strchr(make,' '))) {
+ strcpy (model, cp+1);
+ *cp = 0;
+ }
+ raw_width = get2();
+ raw_height = get2();
+ load_raw = &CLASS unpacked_load_raw;
+ thumb_width = (get4(),get2());
+ thumb_height = get2();
+ write_thumb = &CLASS ppm_thumb;
+ maximum = 0x3fff;
+}
+
+void CLASS parse_phase_one (int base)
+{
+ unsigned entries, tag, type, len, data, save, i, c;
+ float romm_cam[3][3];
+ char *cp;
+
+ memset (&ph1, 0, sizeof ph1);
+ fseek (ifp, base, SEEK_SET);
+ order = get4() & 0xffff;
+ if (get4() >> 8 != 0x526177) return; /* "Raw" */
+ fseek (ifp, base+get4(), SEEK_SET);
+ entries = get4();
+ get4();
+ while (entries--) {
+ tag = get4();
+ type = get4();
+ len = get4();
+ data = get4();
+ save = ftell(ifp);
+ fseek (ifp, base+data, SEEK_SET);
+ switch (tag) {
+ case 0x100: flip = "0653"[data & 3]-'0'; break;
+ case 0x106:
+ for (i=0; i < 9; i++)
+ romm_cam[0][i] = getreal(11);
+ romm_coeff (romm_cam);
+ break;
+ case 0x107:
+ FORC3 cam_mul[c] = getreal(11);
+ break;
+ case 0x108: raw_width = data; break;
+ case 0x109: raw_height = data; break;
+ case 0x10a: left_margin = data; break;
+ case 0x10b: top_margin = data; break;
+ case 0x10c: width = data; break;
+ case 0x10d: height = data; break;
+ case 0x10e: ph1.format = data; break;
+ case 0x10f: data_offset = data+base; break;
+ case 0x110: meta_offset = data+base;
+ meta_length = len; break;
+ case 0x112: ph1.key_off = save - 4; break;
+ case 0x210: ph1.tag_210 = int_to_float(data); break;
+ case 0x21a: ph1.tag_21a = data; break;
+ case 0x21c: strip_offset = data+base; break;
+ case 0x21d: ph1.black = data; break;
+ case 0x222: ph1.split_col = data - left_margin; break;
+ case 0x223: ph1.black_off = data+base; break;
+ case 0x301:
+ model[63] = 0;
+ fread (model, 1, 63, ifp);
+ if ((cp = strstr(model," camera"))) *cp = 0;
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+ load_raw = ph1.format < 3 ?
+ &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
+ maximum = 0xffff;
+ strcpy (make, "Phase One");
+ if (model[0]) return;
+ switch (raw_height) {
+ case 2060: strcpy (model,"LightPhase"); break;
+ case 2682: strcpy (model,"H 10"); break;
+ case 4128: strcpy (model,"H 20"); break;
+ case 5488: strcpy (model,"H 25"); break;
+ }
+}
+
+void CLASS parse_fuji (int offset)
+{
+ unsigned entries, tag, len, save, c;
+
+ fseek (ifp, offset, SEEK_SET);
+ entries = get4();
+ if (entries > 255) return;
+ while (entries--) {
+ tag = get2();
+ len = get2();
+ save = ftell(ifp);
+ if (tag == 0x100) {
+ raw_height = get2();
+ raw_width = get2();
+ } else if (tag == 0x121) {
+ height = get2();
+ if ((width = get2()) == 4284) width += 3;
+ } else if (tag == 0x130)
+ fuji_layout = fgetc(ifp) >> 7;
+ if (tag == 0x2ff0)
+ FORC4 cam_mul[c ^ 1] = get2();
+ fseek (ifp, save+len, SEEK_SET);
+ }
+ height <<= fuji_layout;
+ width >>= fuji_layout;
+}
+
+int CLASS parse_jpeg (int offset)
+{
+ int len, save, hlen, mark;
+
+ fseek (ifp, offset, SEEK_SET);
+ if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
+
+ while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
+ order = 0x4d4d;
+ len = get2() - 2;
+ save = ftell(ifp);
+ if (mark == 0xc0 || mark == 0xc3) {
+ fgetc(ifp);
+ raw_height = get2();
+ raw_width = get2();
+ }
+ order = get2();
+ hlen = get4();
+ if (get4() == 0x48454150) /* "HEAP" */
+ parse_ciff (save+hlen, len-hlen);
+ parse_tiff (save+6);
+ fseek (ifp, save+len, SEEK_SET);
+ }
+ return 1;
+}
+
+void CLASS parse_riff()
+{
+ unsigned i, size, end;
+ char tag[4], date[64], month[64];
+ static const char mon[12][4] =
+ { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
+ struct tm t;
+
+ order = 0x4949;
+ fread (tag, 4, 1, ifp);
+ size = get4();
+ if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
+ end = ftell(ifp) + size;
+ get4();
+ while (ftell(ifp) < end)
+ parse_riff();
+ } else if (!memcmp(tag,"IDIT",4) && size < 64) {
+ fread (date, 64, 1, ifp);
+ date[size] = 0;
+ memset (&t, 0, sizeof t);
+ if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
+ &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
+ for (i=0; i < 12 && strcmp(mon[i],month); i++);
+ t.tm_mon = i;
+ t.tm_year -= 1900;
+ if (mktime(&t) > 0)
+ timestamp = mktime(&t);
+ }
+ } else
+ fseek (ifp, size, SEEK_CUR);
+}
+
+void CLASS parse_smal (int offset, int fsize)
+{
+ int ver;
+
+ fseek (ifp, offset+2, SEEK_SET);
+ order = 0x4949;
+ ver = fgetc(ifp);
+ if (ver == 6)
+ fseek (ifp, 5, SEEK_CUR);
+ if (get4() != fsize) return;
+ if (ver > 6) data_offset = get4();
+ raw_height = height = get2();
+ raw_width = width = get2();
+ strcpy (make, "SMaL");
+ sprintf (model, "v%d %dx%d", ver, width, height);
+ if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
+ if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
+}
+
+void CLASS parse_cine()
+{
+ unsigned off_head, off_setup, off_image, i;
+
+ order = 0x4949;
+ fseek (ifp, 4, SEEK_SET);
+ is_raw = get2() == 2;
+ fseek (ifp, 14, SEEK_CUR);
+ is_raw *= get4();
+ off_head = get4();
+ off_setup = get4();
+ off_image = get4();
+ timestamp = get4();
+ if ((i = get4())) timestamp = i;
+ fseek (ifp, off_head+4, SEEK_SET);
+ raw_width = get4();
+ raw_height = get4();
+ switch (get2(),get2()) {
+ case 8: load_raw = &CLASS eight_bit_load_raw; break;
+ case 16: load_raw = &CLASS unpacked_load_raw;
+ }
+ fseek (ifp, off_setup+792, SEEK_SET);
+ strcpy (make, "CINE");
+ sprintf (model, "%d", get4());
+ fseek (ifp, 12, SEEK_CUR);
+ switch ((i=get4()) & 0xffffff) {
+ case 3: filters = 0x94949494; break;
+ case 4: filters = 0x49494949; break;
+ default: is_raw = 0;
+ }
+ fseek (ifp, 72, SEEK_CUR);
+ switch ((get4()+3600) % 360) {
+ case 270: flip = 4; break;
+ case 180: flip = 1; break;
+ case 90: flip = 7; break;
+ case 0: flip = 2;
+ }
+ cam_mul[0] = getreal(11);
+ cam_mul[2] = getreal(11);
+ maximum = ~(-1 << get4());
+ fseek (ifp, 668, SEEK_CUR);
+ shutter = get4()/1000000000.0;
+ fseek (ifp, off_image, SEEK_SET);
+ if (shot_select < is_raw)
+ fseek (ifp, shot_select*8, SEEK_CUR);
+ data_offset = (INT64) get4() + 8;
+ data_offset += (INT64) get4() << 32;
+}
+
+char * CLASS foveon_gets (int offset, char *str, int len)
+{
+ int i;
+ fseek (ifp, offset, SEEK_SET);
+ for (i=0; i < len-1; i++)
+ if ((str[i] = get2()) == 0) break;
+ str[i] = 0;
+ return str;
+}
+
+void CLASS parse_foveon()
+{
+ int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
+ char name[64], value[64];
+
+ order = 0x4949; /* Little-endian */
+ fseek (ifp, 36, SEEK_SET);
+ flip = get4();
+ fseek (ifp, -4, SEEK_END);
+ fseek (ifp, get4(), SEEK_SET);
+ if (get4() != 0x64434553) return; /* SECd */
+ entries = (get4(),get4());
+ while (entries--) {
+ off = get4();
+ len = get4();
+ tag = get4();
+ save = ftell(ifp);
+ fseek (ifp, off, SEEK_SET);
+ if (get4() != (0x20434553 | (tag << 24))) return;
+ switch (tag) {
+ case 0x47414d49: /* IMAG */
+ case 0x32414d49: /* IMA2 */
+ fseek (ifp, 12, SEEK_CUR);
+ wide = get4();
+ high = get4();
+ if (wide > raw_width && high > raw_height) {
+ raw_width = wide;
+ raw_height = high;
+ data_offset = off+24;
+ }
+ fseek (ifp, off+28, SEEK_SET);
+ if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8) {
+ thumb_offset = off+28;
+ thumb_length = len-28;
+ write_thumb = &CLASS jpeg_thumb;
+ }
+ if (++img == 2 && !thumb_length) {
+ thumb_offset = off+24;
+ thumb_width = wide;
+ thumb_height = high;
+ write_thumb = &CLASS foveon_thumb;
+ }
+ break;
+ case 0x464d4143: /* CAMF */
+ meta_offset = off+24;
+ meta_length = len-28;
+ if (meta_length > 0x20000)
+ meta_length = 0x20000;
+ break;
+ case 0x504f5250: /* PROP */
+ pent = (get4(),get4());
+ fseek (ifp, 12, SEEK_CUR);
+ off += pent*8 + 24;
+ if ((unsigned) pent > 256) pent=256;
+ for (i=0; i < pent*2; i++)
+ poff[0][i] = off + get4()*2;
+ for (i=0; i < pent; i++) {
+ foveon_gets (poff[i][0], name, 64);
+ foveon_gets (poff[i][1], value, 64);
+ if (!strcmp (name, "ISO"))
+ iso_speed = atoi(value);
+ if (!strcmp (name, "CAMMANUF"))
+ strcpy (make, value);
+ if (!strcmp (name, "CAMMODEL"))
+ strcpy (model, value);
+ if (!strcmp (name, "WB_DESC"))
+ strcpy (model2, value);
+ if (!strcmp (name, "TIME"))
+ timestamp = atoi(value);
+ if (!strcmp (name, "EXPTIME"))
+ shutter = atoi(value) / 1000000.0;
+ if (!strcmp (name, "APERTURE"))
+ aperture = atof(value);
+ if (!strcmp (name, "FLENGTH"))
+ focal_len = atof(value);
+ }
+#ifdef LOCALTIME
+ timestamp = mktime (gmtime (&timestamp));
+#endif
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+ is_foveon = 1;
+}
+
+/*
+ Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
+ */
+void CLASS adobe_coeff (char *make, char *model)
+{
+ static const struct {
+ const char *prefix;
+ short black, trans[12];
+ } table[] = {
+ { "Apple QuickTake", 0, /* DJC */
+ { 17576,-3191,-3318,5210,6733,-1942,9031,1280,-124 } },
+ { "Canon EOS D2000", 0,
+ { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
+ { "Canon EOS D6000", 0,
+ { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
+ { "Canon EOS D30", 0,
+ { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
+ { "Canon EOS D60", 0,
+ { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
+ { "Canon EOS 5D", 0,
+ { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
+ { "Canon EOS 20Da", 0,
+ { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
+ { "Canon EOS 20D", 0,
+ { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
+ { "Canon EOS 30D", 0,
+ { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
+ { "Canon EOS 40D", 0,
+ { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
+ { "Canon EOS 350D", 0,
+ { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
+ { "Canon EOS 400D", 0,
+ { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
+ { "Canon EOS-1Ds Mark II", 0,
+ { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
+ { "Canon EOS-1D Mark II N", 0,
+ { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
+ { "Canon EOS-1D Mark III", 0,
+ { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
+ { "Canon EOS-1D Mark II", 0,
+ { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
+ { "Canon EOS-1DS", 0,
+ { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
+ { "Canon EOS-1D", 0,
+ { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
+ { "Canon EOS", 0,
+ { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
+ { "Canon PowerShot A50", 0,
+ { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
+ { "Canon PowerShot A5", 0,
+ { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
+ { "Canon PowerShot G1", 0,
+ { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
+ { "Canon PowerShot G2", 0,
+ { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
+ { "Canon PowerShot G3", 0,
+ { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
+ { "Canon PowerShot G5", 0,
+ { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
+ { "Canon PowerShot G6", 0,
+ { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
+ { "Canon PowerShot G9", 0,
+ { 10823,-3042,-1842,-4562,13656,900,-1311,1670,3556 } },
+ { "Canon PowerShot Pro1", 0,
+ { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
+ { "Canon PowerShot Pro70", 34,
+ { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
+ { "Canon PowerShot Pro90", 0,
+ { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
+ { "Canon PowerShot S30", 0,
+ { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
+ { "Canon PowerShot S40", 0,
+ { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
+ { "Canon PowerShot S45", 0,
+ { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
+ { "Canon PowerShot S50", 0,
+ { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
+ { "Canon PowerShot S60", 0,
+ { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
+ { "Canon PowerShot S70", 0,
+ { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
+ { "Canon PowerShot A610", 0, /* DJC */
+ { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
+ { "Canon PowerShot A620", 0, /* DJC */
+ { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
+ { "Canon PowerShot A640", 0, /* DJC */
+ { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
+ { "Canon PowerShot S3 IS", 0, /* DJC */
+ { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
+ { "CINE 650", 0,
+ { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
+ { "CINE 660", 0,
+ { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
+ { "CINE", 0,
+ { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
+ { "Contax N Digital", 0,
+ { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
+ { "EPSON R-D1", 0,
+ { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
+ { "FUJIFILM FinePix E550", 0,
+ { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
+ { "FUJIFILM FinePix E900", 0,
+ { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
+ { "FUJIFILM FinePix F8", 0,
+ { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
+ { "FUJIFILM FinePix F7", 0,
+ { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
+ { "FUJIFILM FinePix S20Pro", 0,
+ { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
+ { "FUJIFILM FinePix S2Pro", 128,
+ { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
+ { "FUJIFILM FinePix S3Pro", 0,
+ { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
+ { "FUJIFILM FinePix S5Pro", 0,
+ { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
+ { "FUJIFILM FinePix S5000", 0,
+ { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
+ { "FUJIFILM FinePix S5100", 0,
+ { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
+ { "FUJIFILM FinePix S5500", 0,
+ { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
+ { "FUJIFILM FinePix S5200", 0,
+ { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
+ { "FUJIFILM FinePix S5600", 0,
+ { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
+ { "FUJIFILM FinePix S6", 0,
+ { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
+ { "FUJIFILM FinePix S7000", 0,
+ { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
+ { "FUJIFILM FinePix S9000", 0,
+ { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
+ { "FUJIFILM FinePix S9500", 0,
+ { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
+ { "FUJIFILM FinePix S9100", 0,
+ { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
+ { "FUJIFILM FinePix S9600", 0,
+ { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
+ { "Imacon Ixpress", 0, /* DJC */
+ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
+ { "KODAK NC2000", 0, /* DJC */
+ { 16475,-6903,-1218,-851,10375,477,2505,-7,1020 } },
+ { "Kodak DCS315C", 8,
+ { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
+ { "Kodak DCS330C", 8,
+ { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
+ { "KODAK DCS420", 0,
+ { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
+ { "KODAK DCS460", 0,
+ { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
+ { "KODAK EOSDCS1", 0,
+ { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
+ { "KODAK EOSDCS3B", 0,
+ { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
+ { "Kodak DCS520C", 180,
+ { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
+ { "Kodak DCS560C", 188,
+ { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
+ { "Kodak DCS620C", 180,
+ { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
+ { "Kodak DCS620X", 185,
+ { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
+ { "Kodak DCS660C", 214,
+ { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
+ { "Kodak DCS720X", 0,
+ { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
+ { "Kodak DCS760C", 0,
+ { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
+ { "Kodak DCS Pro SLR", 0,
+ { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
+ { "Kodak DCS Pro 14nx", 0,
+ { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
+ { "Kodak DCS Pro 14", 0,
+ { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
+ { "Kodak ProBack645", 0,
+ { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
+ { "Kodak ProBack", 0,
+ { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
+ { "KODAK P712", 0,
+ { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
+ { "KODAK P850", 0,
+ { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
+ { "KODAK P880", 0,
+ { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
+ { "Leaf CMost", 0,
+ { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
+ { "Leaf Valeo 6", 0,
+ { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
+ { "Leaf Aptus 54S", 0,
+ { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
+ { "Leaf Aptus 65", 0,
+ { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
+ { "Leaf Aptus 75", 0,
+ { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
+ { "Leaf", 0,
+ { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
+ { "Mamiya ZD", 0,
+ { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
+ { "Micron 2010", 110, /* DJC */
+ { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
+ { "Minolta DiMAGE 5", 0,
+ { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
+ { "Minolta DiMAGE 7Hi", 0,
+ { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
+ { "Minolta DiMAGE 7", 0,
+ { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
+ { "Minolta DiMAGE A1", 0,
+ { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
+ { "MINOLTA DiMAGE A200", 0,
+ { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
+ { "Minolta DiMAGE A2", 0,
+ { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
+ { "Minolta DiMAGE Z2", 0, /* DJC */
+ { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
+ { "MINOLTA DYNAX 5", 0,
+ { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
+ { "MINOLTA DYNAX 7", 0,
+ { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
+ { "NIKON D100", 0,
+ { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
+ { "NIKON D1H", 0,
+ { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
+ { "NIKON D1X", 0,
+ { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
+ { "NIKON D1", 0, /* multiplied by 2.218750, 1.0, 1.148438 */
+ { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
+ { "NIKON D2H", 0,
+ { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
+ { "NIKON D2X", 0,
+ { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
+ { "NIKON D40X", 0,
+ { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
+ { "NIKON D40", 0,
+ { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
+ { "NIKON D50", 0,
+ { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
+ { "NIKON D70", 0,
+ { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
+ { "NIKON D80", 0,
+ { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
+ { "NIKON D200", 0,
+ { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
+ { "NIKON D300", 0,
+ { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
+ { "NIKON D3", 0,
+ { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
+ { "NIKON E950", 0, /* DJC */
+ { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
+ { "NIKON E995", 0, /* copied from E5000 */
+ { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
+ { "NIKON E2500", 0,
+ { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
+ { "NIKON E4300", 0, /* copied from Minolta DiMAGE Z2 */
+ { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
+ { "NIKON E4500", 0,
+ { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
+ { "NIKON E5000", 0,
+ { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
+ { "NIKON E5400", 0,
+ { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
+ { "NIKON E5700", 0,
+ { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
+ { "NIKON E8400", 0,
+ { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
+ { "NIKON E8700", 0,
+ { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
+ { "NIKON E8800", 0,
+ { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
+ { "OLYMPUS C5050", 0,
+ { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
+ { "OLYMPUS C5060", 0,
+ { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
+ { "OLYMPUS C7070", 0,
+ { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
+ { "OLYMPUS C70", 0,
+ { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
+ { "OLYMPUS C80", 0,
+ { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
+ { "OLYMPUS E-10", 0,
+ { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
+ { "OLYMPUS E-1", 0,
+ { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
+ { "OLYMPUS E-20", 0,
+ { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
+ { "OLYMPUS E-300", 0,
+ { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
+ { "OLYMPUS E-330", 0,
+ { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
+ { "OLYMPUS E-3", 0,
+ { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
+ { "OLYMPUS E-400", 0,
+ { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
+ { "OLYMPUS E-410", 0,
+ { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
+ { "OLYMPUS E-500", 0,
+ { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
+ { "OLYMPUS E-510", 0,
+ { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
+ { "OLYMPUS SP350", 0,
+ { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
+ { "OLYMPUS SP3", 0,
+ { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
+ { "OLYMPUS SP500UZ", 0,
+ { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
+ { "OLYMPUS SP510UZ", 0,
+ { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
+ { "OLYMPUS SP550UZ", 0,
+ { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
+ { "PENTAX *ist DL2", 0,
+ { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
+ { "PENTAX *ist DL", 0,
+ { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
+ { "PENTAX *ist DS2", 0,
+ { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
+ { "PENTAX *ist DS", 0,
+ { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
+ { "PENTAX *ist D", 0,
+ { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
+ { "PENTAX K10D", 0,
+ { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
+ { "PENTAX K1", 0,
+ { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
+ { "Panasonic DMC-FZ8", 0,
+ { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
+ { "Panasonic DMC-FZ18", 0,
+ { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
+ { "Panasonic DMC-FZ30", 0,
+ { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
+ { "Panasonic DMC-FZ50", 0, /* aka "LEICA V-LUX1" */
+ { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
+ { "Panasonic DMC-L1", 0, /* aka "LEICA DIGILUX 3" */
+ { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
+ { "Panasonic DMC-LC1", 0, /* aka "LEICA DIGILUX 2" */
+ { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
+ { "Panasonic DMC-LX1", 0, /* aka "LEICA D-LUX2" */
+ { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
+ { "Panasonic DMC-LX2", 0, /* aka "LEICA D-LUX3" */
+ { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
+ { "Phase One H 20", 0, /* DJC */
+ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
+ { "Phase One P 2", 0,
+ { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
+ { "Phase One P 30", 0,
+ { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
+ { "Phase One P 45", 0,
+ { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
+ { "SAMSUNG GX-1", 0,
+ { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
+ { "Sinar", 0, /* DJC */
+ { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
+ { "SONY DSC-F828", 491,
+ { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
+ { "SONY DSC-R1", 512,
+ { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
+ { "SONY DSC-V3", 0,
+ { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
+ { "SONY DSLR-A100", 0,
+ { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
+ { "SONY DSLR-A700", 254,
+ { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }
+ };
+ double cam_xyz[4][3];
+ char name[130];
+ int i, j;
+
+ sprintf (name, "%s %s", make, model);
+ for (i=0; i < sizeof table / sizeof *table; i++)
+ if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
+ if (table[i].black)
+ black = table[i].black;
+ for (j=0; j < 12; j++)
+ cam_xyz[0][j] = table[i].trans[j] / 10000.0;
+ cam_xyz_coeff (cam_xyz);
+ break;
+ }
+}
+
+void CLASS simple_coeff (int index)
+{
+ static const float table[][12] = {
+ /* index 0 -- all Foveon cameras */
+ { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
+ /* index 1 -- Kodak DC20 and DC25 */
+ { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
+ /* index 2 -- Logitech Fotoman Pixtura */
+ { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
+ /* index 3 -- Nikon E880, E900, and E990 */
+ { -1.936280, 1.800443, -1.448486, 2.584324,
+ 1.405365, -0.524955, -0.289090, 0.408680,
+ -1.204965, 1.082304, 2.941367, -1.818705 }
+ };
+ int i, c;
+
+ for (raw_color = i=0; i < 3; i++)
+ FORCC rgb_cam[i][c] = table[index][i*colors+c];
+}
+
+short CLASS guess_byte_order (int words)
+{
+ uchar test[4][2];
+ int t=2, msb;
+ double diff, sum[2] = {0,0};
+
+ fread (test[0], 2, 2, ifp);
+ for (words-=2; words--; ) {
+ fread (test[t], 2, 1, ifp);
+ for (msb=0; msb < 2; msb++) {
+ diff = (test[t^2][msb] << 8 | test[t^2][!msb])
+ - (test[t ][msb] << 8 | test[t ][!msb]);
+ sum[msb] += diff*diff;
+ }
+ t = (t+1) & 3;
+ }
+ return sum[0] < sum[1] ? 0x4d4d : 0x4949;
+}
+
+/*
+ Identify which camera created this file, and set global variables
+ accordingly.
+ */
+void CLASS identify()
+{
+ char head[32], *cp;
+ unsigned hlen, fsize, i, c, is_canon;
+ struct jhead jh;
+ static const struct {
+ int fsize;
+ char make[12], model[19], withjpeg;
+ } table[] = {
+ { 62464, "Kodak", "DC20" ,0 },
+ { 124928, "Kodak", "DC20" ,0 },
+ { 1652736, "Kodak", "DCS200" ,0 },
+ { 4159302, "Kodak", "C330" ,0 },
+ { 4162462, "Kodak", "C330" ,0 },
+ { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */
+ { 614400, "Kodak", "KAI-0340" ,0 },
+ { 787456, "Creative", "PC-CAM 600" ,0 },
+ { 1138688, "Minolta", "RD175" ,0 },
+ { 3840000, "Foculus", "531C" ,0 },
+ { 786432, "AVT", "F-080C" ,0 },
+ { 1447680, "AVT", "F-145C" ,0 },
+ { 1920000, "AVT", "F-201C" ,0 },
+ { 5067304, "AVT", "F-510C" ,0 },
+ { 10134608, "AVT", "F-510C" ,0 },
+ { 16157136, "AVT", "F-810C" ,0 },
+ { 1409024, "Sony", "XCD-SX910CR",0 },
+ { 2818048, "Sony", "XCD-SX910CR",0 },
+ { 3884928, "Micron", "2010" ,0 },
+ { 6624000, "Pixelink", "A782" ,0 },
+ { 13248000, "Pixelink", "A782" ,0 },
+ { 6291456, "RoverShot","3320AF" ,0 },
+ { 6573120, "Canon", "PowerShot A610",0 },
+ { 9219600, "Canon", "PowerShot A620",0 },
+ { 10383120, "Canon", "PowerShot A630",0 },
+ { 12945240, "Canon", "PowerShot A640",0 },
+ { 7710960, "Canon", "PowerShot S3 IS",0 },
+ { 5939200, "OLYMPUS", "C770UZ" ,0 },
+ { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */
+ { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */
+ { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */
+ { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */
+ { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */
+ { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */
+ { 5865472, "NIKON", "E4500" ,1 },
+ { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */
+ { 8998912, "NIKON", "COOLPIX S6" ,1 },
+ { 1976352, "CASIO", "QV-2000UX" ,1 },
+ { 3217760, "CASIO", "QV-3*00EX" ,1 },
+ { 6218368, "CASIO", "QV-5700" ,1 },
+ { 6054400, "CASIO", "QV-R41" ,1 },
+ { 7530816, "CASIO", "QV-R51" ,1 },
+ { 7684000, "CASIO", "QV-4000" ,1 },
+ { 4948608, "CASIO", "EX-S100" ,1 },
+ { 7542528, "CASIO", "EX-Z50" ,1 },
+ { 7753344, "CASIO", "EX-Z55" ,1 },
+ { 7426656, "CASIO", "EX-P505" ,1 },
+ { 9313536, "CASIO", "EX-P600" ,1 },
+ { 10979200, "CASIO", "EX-P700" ,1 },
+ { 3178560, "PENTAX", "Optio S" ,1 },
+ { 4841984, "PENTAX", "Optio S" ,1 },
+ { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */
+ { 10702848, "PENTAX", "Optio 750Z" ,1 },
+ { 12582980, "Sinar", "" ,0 },
+ { 33292868, "Sinar", "" ,0 },
+ { 44390468, "Sinar", "" ,0 } };
+ static const char *corp[] =
+ { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
+ "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
+ "SAMSUNG", "Mamiya" };
+
+ tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */
+ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
+ maximum = height = width = top_margin = left_margin = 0;
+ cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
+ iso_speed = shutter = aperture = focal_len = unique_id = 0;
+ memset (white, 0, sizeof white);
+ thumb_offset = thumb_length = thumb_width = thumb_height = 0;
+ load_raw = thumb_load_raw = 0;
+ write_thumb = &CLASS jpeg_thumb;
+ data_offset = meta_length = tiff_bps = tiff_compress = 0;
+ kodak_cbpp = zero_after_ff = dng_version = 0;
+ timestamp = shot_order = tiff_samples = black = is_foveon = 0;
+ mix_green = profile_length = data_error = zero_is_bad = 0;
+ pixel_aspect = is_raw = raw_color = use_gamma = 1;
+ tile_width = tile_length = INT_MAX;
+ for (i=0; i < 4; i++) {
+ cam_mul[i] = i == 1;
+ pre_mul[i] = i < 3;
+ FORC3 cmatrix[c][i] = 0;
+ FORC3 rgb_cam[c][i] = c == i;
+ }
+ colors = 3;
+ tiff_bps = 12;
+ for (i=0; i < 0x4000; i++) curve[i] = i;
+
+ order = get2();
+ hlen = get4();
+ fseek (ifp, 0, SEEK_SET);
+ fread (head, 1, 32, ifp);
+ fseek (ifp, 0, SEEK_END);
+ fsize = ftell(ifp);
+ if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
+ (cp = (char *) memmem (head, 32, "IIII", 4))) {
+ parse_phase_one (cp-head);
+ if (cp-head) parse_tiff(0);
+ } else if (order == 0x4949 || order == 0x4d4d) {
+ if (!memcmp (head+6,"HEAPCCDR",8)) {
+ data_offset = hlen;
+ parse_ciff (hlen, fsize - hlen);
+ } else {
+ parse_tiff(0);
+ }
+ } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
+ !memcmp (head+6,"Exif",4)) {
+ fseek (ifp, 4, SEEK_SET);
+ data_offset = 4 + get2();
+ fseek (ifp, data_offset, SEEK_SET);
+ if (fgetc(ifp) != 0xff)
+ parse_tiff(12);
+ thumb_offset = 0;
+ } else if (!memcmp (head+25,"ARECOYK",7)) {
+ strcpy (make, "Contax");
+ strcpy (model,"N Digital");
+ fseek (ifp, 33, SEEK_SET);
+ get_timestamp(1);
+ fseek (ifp, 60, SEEK_SET);
+ FORC4 cam_mul[c ^ (c >> 1)] = get4();
+ } else if (!strcmp (head, "PXN")) {
+ strcpy (make, "Logitech");
+ strcpy (model,"Fotoman Pixtura");
+ } else if (!strcmp (head, "qktk")) {
+ strcpy (make, "Apple");
+ strcpy (model,"QuickTake 100");
+ } else if (!strcmp (head, "qktn")) {
+ strcpy (make, "Apple");
+ strcpy (model,"QuickTake 150");
+ } else if (!memcmp (head,"FUJIFILM",8)) {
+ fseek (ifp, 84, SEEK_SET);
+ thumb_offset = get4();
+ thumb_length = get4();
+ fseek (ifp, 92, SEEK_SET);
+ parse_fuji (get4());
+ if (thumb_offset > 120) {
+ fseek (ifp, 120, SEEK_SET);
+ is_raw += (i = get4()) && 1;
+ if (is_raw == 2 && shot_select)
+ parse_fuji (i);
+ }
+ fseek (ifp, 100, SEEK_SET);
+ data_offset = get4();
+ parse_tiff (thumb_offset+12);
+ } else if (!memcmp (head,"RIFF",4)) {
+ fseek (ifp, 0, SEEK_SET);
+ parse_riff();
+ } else if (!memcmp (head,"DSC-Image",9))
+ parse_rollei();
+ else if (!memcmp (head,"PWAD",4))
+ parse_sinar_ia();
+ else if (!memcmp (head,"\0MRM",4))
+ parse_minolta(0);
+ else if (!memcmp (head,"FOVb",4))
+ parse_foveon();
+ else if (!memcmp (head,"CI",2))
+ parse_cine();
+ else
+ for (i=0; i < sizeof table / sizeof *table; i++)
+ if (fsize == table[i].fsize) {
+ strcpy (make, table[i].make );
+ strcpy (model, table[i].model);
+ if (table[i].withjpeg)
+ parse_external_jpeg();
+ }
+ if (make[0] == 0) parse_smal (0, fsize);
+ if (make[0] == 0) parse_jpeg (is_raw = 0);
+
+ for (i=0; i < sizeof corp / sizeof *corp; i++)
+ if (strstr (make, corp[i])) /* Simplify company names */
+ strcpy (make, corp[i]);
+ if (!strncmp (make,"KODAK",5))
+ make[16] = model[16] = 0;
+ cp = make + strlen(make); /* Remove trailing spaces */
+ while (*--cp == ' ') *cp = 0;
+ cp = model + strlen(model);
+ while (*--cp == ' ') *cp = 0;
+ i = strlen(make); /* Remove make from model */
+ if (!strncasecmp (model, make, i) && model[i++] == ' ')
+ memmove (model, model+i, 64-i);
+ if (!strncmp (model,"Digital Camera ",15))
+ strcpy (model, model+15);
+ desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
+ if (!is_raw) goto notraw;
+
+ if (!maximum) maximum = (1 << tiff_bps) - 1;
+ if (!height) height = raw_height;
+ if (!width) width = raw_width;
+ if (fuji_width) {
+ width = height + fuji_width;
+ height = width - 1;
+ pixel_aspect = 1;
+ }
+ if (height == 2624 && width == 3936) { /* Pentax K10D and Samsung GX10 */
+ height = 2616;
+ width = 3896;
+ }
+ if (dng_version) {
+ if (filters == UINT_MAX) filters = 0;
+ if (filters) is_raw = tiff_samples;
+ else colors = tiff_samples;
+ if (tiff_compress == 1)
+ load_raw = &CLASS adobe_dng_load_raw_nc;
+ if (tiff_compress == 7)
+ load_raw = &CLASS adobe_dng_load_raw_lj;
+ goto dng_skip;
+ }
+ if ((is_canon = !strcmp(make,"Canon"))) {
+ load_raw = memcmp (head+6,"HEAPCCDR",8) ?
+ &CLASS lossless_jpeg_load_raw : &CLASS canon_compressed_load_raw;
+ maximum = 0xfff;
+ }
+ if (!strcmp(make,"NIKON") && !load_raw)
+ load_raw = &CLASS nikon_load_raw;
+
+/* Set parameters based on camera name (for non-DNG files). */
+
+ if (is_foveon) {
+ if (height*2 < width) pixel_aspect = 0.5;
+ if (height > width) pixel_aspect = 2;
+ filters = 0;
+ load_raw = &CLASS foveon_load_raw;
+ simple_coeff(0);
+ } else if (is_canon && tiff_samples == 4) {
+ filters = 0;
+ load_raw = &CLASS canon_sraw_load_raw;
+ } else if (!strcmp(model,"PowerShot 600")) {
+ height = 613;
+ width = 854;
+ raw_width = 896;
+ pixel_aspect = 607/628.0;
+ colors = 4;
+ filters = 0xe1e4e1e4;
+ load_raw = &CLASS canon_600_load_raw;
+ } else if (!strcmp(model,"PowerShot A5") ||
+ !strcmp(model,"PowerShot A5 Zoom")) {
+ height = 773;
+ width = 960;
+ raw_width = 992;
+ pixel_aspect = 256/235.0;
+ colors = 4;
+ filters = 0x1e4e1e4e;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot A50")) {
+ height = 968;
+ width = 1290;
+ raw_width = 1320;
+ colors = 4;
+ filters = 0x1b4e4b1e;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot Pro70")) {
+ height = 1024;
+ width = 1552;
+ colors = 4;
+ filters = 0x1e4b4e1b;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot A610")) {
+ if (canon_s2is()) strcpy (model+10, "S2 IS");
+ height = 1960;
+ width = 2616;
+ raw_height = 1968;
+ raw_width = 2672;
+ top_margin = 8;
+ left_margin = 12;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot A620")) {
+ height = 2328;
+ width = 3112;
+ raw_height = 2340;
+ raw_width = 3152;
+ top_margin = 12;
+ left_margin = 36;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot A630")) {
+ height = 2472;
+ width = 3288;
+ raw_height = 2484;
+ raw_width = 3344;
+ top_margin = 6;
+ left_margin = 12;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot A640")) {
+ height = 2760;
+ width = 3672;
+ raw_height = 2772;
+ raw_width = 3736;
+ top_margin = 6;
+ left_margin = 12;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot S3 IS")) {
+ height = 2128;
+ width = 2840;
+ raw_height = 2136;
+ raw_width = 2888;
+ top_margin = 8;
+ left_margin = 44;
+ load_raw = &CLASS canon_a5_load_raw;
+ } else if (!strcmp(model,"PowerShot Pro90 IS")) {
+ width = 1896;
+ colors = 4;
+ filters = 0xb4b4b4b4;
+ } else if (is_canon && raw_width == 2144) {
+ height = 1550;
+ width = 2088;
+ top_margin = 8;
+ left_margin = 4;
+ if (!strcmp(model,"PowerShot G1")) {
+ colors = 4;
+ filters = 0xb4b4b4b4;
+ }
+ } else if (is_canon && raw_width == 2224) {
+ height = 1448;
+ width = 2176;
+ top_margin = 6;
+ left_margin = 48;
+ } else if (is_canon && raw_width == 2376) {
+ height = 1720;
+ width = 2312;
+ top_margin = 6;
+ left_margin = 12;
+ } else if (is_canon && raw_width == 2672) {
+ height = 1960;
+ width = 2616;
+ top_margin = 6;
+ left_margin = 12;
+ } else if (is_canon && raw_width == 3152) {
+ height = 2056;
+ width = 3088;
+ top_margin = 12;
+ left_margin = 64;
+ if (unique_id == 0x80000170)
+ adobe_coeff ("Canon","EOS 300D");
+ maximum = 0xfa0;
+ } else if (is_canon && raw_width == 3160) {
+ height = 2328;
+ width = 3112;
+ top_margin = 12;
+ left_margin = 44;
+ } else if (is_canon && raw_width == 3344) {
+ height = 2472;
+ width = 3288;
+ top_margin = 6;
+ left_margin = 4;
+ } else if (!strcmp(model,"EOS D2000C")) {
+ filters = 0x61616161;
+ black = curve[200];
+ } else if (is_canon && raw_width == 3516) {
+ top_margin = 14;
+ left_margin = 42;
+ if (unique_id == 0x80000189)
+ adobe_coeff ("Canon","EOS 350D");
+ goto canon_cr2;
+ } else if (is_canon && raw_width == 3596) {
+ top_margin = 12;
+ left_margin = 74;
+ goto canon_cr2;
+ } else if (is_canon && raw_width == 3944) {
+ height = 2602;
+ width = 3908;
+ top_margin = 18;
+ left_margin = 30;
+ maximum = 0x3f60;
+ } else if (is_canon && raw_width == 3948) {
+ top_margin = 18;
+ left_margin = 42;
+ height -= 2;
+ if (unique_id == 0x80000236)
+ adobe_coeff ("Canon","EOS 400D");
+ goto canon_cr2;
+ } else if (is_canon && raw_width == 3984) {
+ top_margin = 20;
+ left_margin = 76;
+ height -= 2;
+ maximum = 0x3bb0;
+ goto canon_cr2;
+ } else if (is_canon && raw_width == 4104) {
+ height = 3024;
+ width = 4032;
+ top_margin = 12;
+ left_margin = 48;
+ } else if (is_canon && raw_width == 4476) {
+ top_margin = 34;
+ left_margin = 90;
+ maximum = 0xe6c;
+ goto canon_cr2;
+ } else if (is_canon && raw_width == 5108) {
+ top_margin = 13;
+ left_margin = 98;
+ maximum = 0xe80;
+canon_cr2:
+ height -= top_margin;
+ width -= left_margin;
+ } else if (is_canon && raw_width == 5712) {
+ height = 3752;
+ width = 5640;
+ top_margin = 20;
+ left_margin = 62;
+ maximum = 0x3bb0;
+ } else if (!strcmp(model,"D1")) {
+ cam_mul[0] *= 256/527.0;
+ cam_mul[2] *= 256/317.0;
+ } else if (!strcmp(model,"D1X")) {
+ width -= 4;
+ pixel_aspect = 0.5;
+ } else if (!strncmp(model,"D40",3) ||
+ !strncmp(model,"D50",3) ||
+ !strncmp(model,"D70",3)) {
+ width--;
+ } else if (!strcmp(model,"D80")) {
+ height -= 3;
+ width -= 4;
+ } else if (!strcmp(model,"D100")) {
+ if (tiff_compress == 34713 && !nikon_is_compressed()) {
+ load_raw = &CLASS nikon_load_raw;
+ raw_width = (width += 3) + 3;
+ }
+ maximum = 0xf44;
+ } else if (!strcmp(model,"D200")) {
+ left_margin = 1;
+ width -= 4;
+ maximum = 0xfbc;
+ filters = 0x94949494;
+ } else if (!strncmp(model,"D2H",3)) {
+ left_margin = 6;
+ width -= 14;
+ } else if (!strcmp(model,"D2X")) {
+ width -= 8;
+ maximum = 0xf35;
+ } else if (!strcmp(model,"D300")) {
+ width -= 32;
+ } else if (fsize == 1581060) {
+ height = 963;
+ width = 1287;
+ raw_width = 1632;
+ load_raw = &CLASS nikon_e900_load_raw;
+ maximum = 0x3f4;
+ colors = 4;
+ filters = 0x1e1e1e1e;
+ simple_coeff(3);
+ pre_mul[0] = 1.2085;
+ pre_mul[1] = 1.0943;
+ pre_mul[3] = 1.1103;
+ } else if (fsize == 2465792) {
+ height = 1203;
+ width = 1616;
+ raw_width = 2048;
+ load_raw = &CLASS nikon_e900_load_raw;
+ maximum = 0x3dd;
+ colors = 4;
+ filters = 0x4b4b4b4b;
+ adobe_coeff ("NIKON","E950");
+ } else if (fsize == 4771840) {
+ height = 1540;
+ width = 2064;
+ colors = 4;
+ filters = 0xe1e1e1e1;
+ load_raw = &CLASS nikon_load_raw;
+ if (!timestamp && nikon_e995())
+ strcpy (model, "E995");
+ if (strcmp(model,"E995")) {
+ filters = 0xb4b4b4b4;
+ simple_coeff(3);
+ pre_mul[0] = 1.196;
+ pre_mul[1] = 1.246;
+ pre_mul[2] = 1.018;
+ }
+ } else if (!strcmp(model,"E2100")) {
+ if (!timestamp && !nikon_e2100()) goto cp_e2500;
+ height = 1206;
+ width = 1616;
+ load_raw = &CLASS nikon_e2100_load_raw;
+ pre_mul[0] = 1.945;
+ pre_mul[2] = 1.040;
+ } else if (!strcmp(model,"E2500")) {
+cp_e2500:
+ strcpy (model, "E2500");
+ height = 1204;
+ width = 1616;
+ colors = 4;
+ filters = 0x4b4b4b4b;
+ } else if (fsize == 4775936) {
+ height = 1542;
+ width = 2064;
+ load_raw = &CLASS nikon_e2100_load_raw;
+ pre_mul[0] = 1.818;
+ pre_mul[2] = 1.618;
+ if (!timestamp) nikon_3700();
+ if (model[0] == 'E' && atoi(model+1) < 3700)
+ filters = 0x49494949;
+ if (!strcmp(model,"Optio 33WR")) {
+ flip = 1;
+ filters = 0x16161616;
+ pre_mul[0] = 1.331;
+ pre_mul[2] = 1.820;
+ }
+ } else if (fsize == 5869568) {
+ height = 1710;
+ width = 2288;
+ filters = 0x16161616;
+ if (!timestamp && minolta_z2()) {
+ strcpy (make, "Minolta");
+ strcpy (model,"DiMAGE Z2");
+ }
+ if (make[0] == 'M')
+ load_raw = &CLASS nikon_e2100_load_raw;
+ } else if (!strcmp(model,"E4500")) {
+ height = 1708;
+ width = 2288;
+ colors = 4;
+ filters = 0xb4b4b4b4;
+ } else if (fsize == 7438336) {
+ height = 1924;
+ width = 2576;
+ colors = 4;
+ filters = 0xb4b4b4b4;
+ } else if (fsize == 8998912) {
+ height = 2118;
+ width = 2832;
+ maximum = 0xf83;
+ load_raw = &CLASS nikon_e2100_load_raw;
+ } else if (!strcmp(model,"FinePix S5100") ||
+ !strcmp(model,"FinePix S5500")) {
+ load_raw = &CLASS unpacked_load_raw;
+ maximum = 0x3e00;
+ } else if (!strncmp(model,"FinePix",7)) {
+ if (!strcmp(model+7,"S2Pro")) {
+ strcpy (model+7," S2Pro");
+ height = 2144;
+ width = 2880;
+ flip = 6;
+ } else
+ maximum = 0x3e00;
+ if (is_raw == 2 && shot_select)
+ maximum = 0x2f00;
+ top_margin = (raw_height - height)/2;
+ left_margin = (raw_width - width )/2;
+ if (is_raw == 2)
+ data_offset += (shot_select > 0) * ( fuji_layout ?
+ (raw_width *= 2) : raw_height*raw_width*2 );
+ fuji_width = width >> !fuji_layout;
+ width = (height >> fuji_layout) + fuji_width;
+ raw_height = height;
+ height = width - 1;
+ load_raw = &CLASS fuji_load_raw;
+ if (!(fuji_width & 1)) filters = 0x49494949;
+ } else if (!strcmp(model,"RD175")) {
+ height = 986;
+ width = 1534;
+ data_offset = 513;
+ filters = 0x61616161;
+ load_raw = &CLASS minolta_rd175_load_raw;
+ } else if (!strcmp(model,"KD-400Z")) {
+ height = 1712;
+ width = 2312;
+ raw_width = 2336;
+ goto konica_400z;
+ } else if (!strcmp(model,"KD-510Z")) {
+ goto konica_510z;
+ } else if (!strcasecmp(make,"MINOLTA")) {
+ load_raw = &CLASS unpacked_load_raw;
+ maximum = 0xf7d;
+ if (!strncmp(model,"DiMAGE A",8)) {
+ if (!strcmp(model,"DiMAGE A200"))
+ filters = 0x49494949;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = model[8] == '1' ? 0xf8b : 0xfff;
+ } else if (!strncmp(model,"ALPHA",5) ||
+ !strncmp(model,"DYNAX",5) ||
+ !strncmp(model,"MAXXUM",6)) {
+ sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
+ adobe_coeff (make, model+20);
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xffb;
+ } else if (!strncmp(model,"DiMAGE G",8)) {
+ if (model[8] == '4') {
+ height = 1716;
+ width = 2304;
+ } else if (model[8] == '5') {
+konica_510z:
+ height = 1956;
+ width = 2607;
+ raw_width = 2624;
+ } else if (model[8] == '6') {
+ height = 2136;
+ width = 2848;
+ }
+ data_offset += 14;
+ filters = 0x61616161;
+konica_400z:
+ load_raw = &CLASS unpacked_load_raw;
+ maximum = 0x3df;
+ order = 0x4d4d;
+ }
+ } else if (!strcmp(model,"*ist DS")) {
+ height -= 2;
+ } else if (!strcmp(model,"Optio S")) {
+ if (fsize == 3178560) {
+ height = 1540;
+ width = 2064;
+ load_raw = &CLASS eight_bit_load_raw;
+ cam_mul[0] *= 4;
+ cam_mul[2] *= 4;
+ pre_mul[0] = 1.391;
+ pre_mul[2] = 1.188;
+ } else {
+ height = 1544;
+ width = 2068;
+ raw_width = 3136;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7c;
+ pre_mul[0] = 1.137;
+ pre_mul[2] = 1.453;
+ }
+ } else if (fsize == 6114240) {
+ height = 1737;
+ width = 2324;
+ raw_width = 3520;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7a;
+ pre_mul[0] = 1.980;
+ pre_mul[2] = 1.570;
+ } else if (!strcmp(model,"Optio 750Z")) {
+ height = 2302;
+ width = 3072;
+ load_raw = &CLASS nikon_e2100_load_raw;
+ } else if (!strcmp(model,"STV680 VGA")) {
+ height = 484;
+ width = 644;
+ load_raw = &CLASS eight_bit_load_raw;
+ flip = 2;
+ filters = 0x16161616;
+ black = 16;
+ pre_mul[0] = 1.097;
+ pre_mul[2] = 1.128;
+ } else if (!strcmp(model,"KAI-0340")) {
+ height = 477;
+ width = 640;
+ order = 0x4949;
+ data_offset = 3840;
+ load_raw = &CLASS unpacked_load_raw;
+ pre_mul[0] = 1.561;
+ pre_mul[2] = 2.454;
+ } else if (!strcmp(model,"531C")) {
+ height = 1200;
+ width = 1600;
+ load_raw = &CLASS unpacked_load_raw;
+ filters = 0x49494949;
+ pre_mul[1] = 1.218;
+ } else if (!strcmp(model,"F-080C")) {
+ height = 768;
+ width = 1024;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (!strcmp(model,"F-145C")) {
+ height = 1040;
+ width = 1392;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (!strcmp(model,"F-201C")) {
+ height = 1200;
+ width = 1600;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (!strcmp(model,"F-510C")) {
+ height = 1958;
+ width = 2588;
+ load_raw = fsize < 7500000 ?
+ &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
+ maximum = 0xfff0;
+ } else if (!strcmp(model,"F-810C")) {
+ height = 2469;
+ width = 3272;
+ load_raw = &CLASS unpacked_load_raw;
+ maximum = 0xfff0;
+ } else if (!strcmp(model,"XCD-SX910CR")) {
+ height = 1024;
+ width = 1375;
+ raw_width = 1376;
+ filters = 0x49494949;
+ maximum = 0x3ff;
+ load_raw = fsize < 2000000 ?
+ &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
+ } else if (!strcmp(model,"2010")) {
+ height = 1207;
+ width = 1608;
+ order = 0x4949;
+ filters = 0x16161616;
+ data_offset = 3212;
+ maximum = 0x3ff;
+ load_raw = &CLASS unpacked_load_raw;
+ } else if (!strcmp(model,"A782")) {
+ height = 3000;
+ width = 2208;
+ filters = 0x61616161;
+ load_raw = fsize < 10000000 ?
+ &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
+ maximum = 0xffc0;
+ } else if (!strcmp(model,"3320AF")) {
+ height = 1536;
+ raw_width = width = 2048;
+ filters = 0x61616161;
+ load_raw = &CLASS unpacked_load_raw;
+ maximum = 0x3ff;
+ pre_mul[0] = 1.717;
+ pre_mul[2] = 1.138;
+ fseek (ifp, 0x300000, SEEK_SET);
+ if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
+ height -= (top_margin = 16);
+ width -= (left_margin = 28);
+ maximum = 0xf5c0;
+ strcpy (make, "ISG");
+ model[0] = 0;
+ }
+ } else if (!strcmp(make,"Hasselblad")) {
+ if (load_raw == lossless_jpeg_load_raw)
+ load_raw = hasselblad_load_raw;
+ } else if (!strcmp(make,"Sinar")) {
+ if (!memcmp(head,"8BPS",4)) {
+ fseek (ifp, 14, SEEK_SET);
+ height = get4();
+ width = get4();
+ filters = 0x61616161;
+ data_offset = 68;
+ }
+ if (!load_raw) load_raw = &CLASS unpacked_load_raw;
+ maximum = 0x3fff;
+ } else if (!strcmp(make,"Leaf")) {
+ maximum = 0x3fff;
+ if (tiff_samples > 1) filters = 0;
+ if (tiff_samples > 1 || tile_length < raw_height)
+ load_raw = &CLASS leaf_hdr_load_raw;
+ if ((width | height) == 2048) {
+ if (tiff_samples == 1) {
+ filters = 1;
+ strcpy (cdesc, "RBTG");
+ strcpy (model, "CatchLight");
+ top_margin = 8; left_margin = 18; height = 2032; width = 2016;
+ } else {
+ strcpy (model, "DCB2");
+ top_margin = 10; left_margin = 16; height = 2028; width = 2022;
+ }
+ } else if (width+height == 3144+2060) {
+ if (!model[0]) strcpy (model, "Cantare");
+ if (width > height) {
+ top_margin = 6; left_margin = 32; height = 2048; width = 3072;
+ filters = 0x61616161;
+ } else {
+ left_margin = 6; top_margin = 32; width = 2048; height = 3072;
+ filters = 0x16161616;
+ }
+ if (!cam_mul[0] || model[0] == 'V') filters = 0;
+ else is_raw = tiff_samples;
+ } else if (width == 2116) {
+ strcpy (model, "Valeo 6");
+ height -= 2 * (top_margin = 30);
+ width -= 2 * (left_margin = 55);
+ filters = 0x49494949;
+ } else if (width == 3171) {
+ strcpy (model, "Valeo 6");
+ height -= 2 * (top_margin = 24);
+ width -= 2 * (left_margin = 24);
+ filters = 0x16161616;
+ }
+ } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
+ maximum = 0xfff0;
+ if (!load_raw) load_raw = &CLASS unpacked_load_raw;
+ switch (width) {
+ case 2568:
+ adobe_coeff ("Panasonic","DMC-LC1"); break;
+ case 3130:
+ left_margin = -14;
+ case 3170:
+ left_margin += 18;
+ width = 3096;
+ if (height > 2326) {
+ height = 2326;
+ top_margin = 13;
+ filters = 0x49494949;
+ }
+ maximum = 0xf7f0;
+ zero_is_bad = 1;
+ adobe_coeff ("Panasonic","DMC-FZ8"); break;
+ case 3177:
+ width -= 10;
+ filters = 0x49494949;
+ maximum = 0xf7fc;
+ zero_is_bad = 1;
+ adobe_coeff ("Panasonic","DMC-L1"); break;
+ case 3304:
+ width -= 16;
+ maximum = 0xf94c;
+ zero_is_bad = 1;
+ adobe_coeff ("Panasonic","DMC-FZ30"); break;
+ case 3330:
+ width = 3291;
+ left_margin = 9;
+ maximum = 0xf7f0;
+ goto fz18;
+ case 3370:
+ width = 3288;
+ left_margin = 15;
+fz18: if (height > 2480)
+ height = 2480 - (top_margin = 10);
+ filters = 0x49494949;
+ zero_is_bad = 1;
+ break;
+ case 3690:
+ height += 36;
+ left_margin = -14;
+ filters = 0x49494949;
+ maximum = 0xf7f0;
+ case 3770:
+ width = 3672;
+ if ((height -= 39) == 2760)
+ top_margin = 15;
+ left_margin += 17;
+ zero_is_bad = 1;
+ adobe_coeff ("Panasonic","DMC-FZ50"); break;
+ case 3880:
+ width -= 22;
+ left_margin = 6;
+ maximum = 0xf7f0;
+ zero_is_bad = 1;
+ adobe_coeff ("Panasonic","DMC-LX1"); break;
+ case 4290:
+ height += 38;
+ left_margin = -14;
+ filters = 0x49494949;
+ case 4330:
+ width = 4248;
+ if ((height -= 39) == 2400)
+ top_margin = 15;
+ left_margin += 17;
+ adobe_coeff ("Panasonic","DMC-LX2"); break;
+ }
+ } else if (!strcmp(model,"C770UZ")) {
+ height = 1718;
+ width = 2304;
+ filters = 0x16161616;
+ load_raw = &CLASS nikon_e2100_load_raw;
+ } else if (!strcmp(make,"OLYMPUS")) {
+ height += height & 1;
+ filters = exif_cfa;
+ if (!strcmp(model,"E-1") ||
+ !strcmp(model,"E-400")) {
+ maximum = 0xfff0;
+ } else if (!strcmp(model,"E-10") ||
+ !strncmp(model,"E-20",4)) {
+ maximum = 0xffc0;
+ black <<= 2;
+ } else if (!strcmp(model,"E-300") ||
+ !strcmp(model,"E-500")) {
+ width -= 20;
+ if (load_raw == &CLASS unpacked_load_raw) {
+ maximum = 0xfc30;
+ black = 0;
+ }
+ } else if (!strcmp(model,"E-330")) {
+ width -= 30;
+ if (load_raw == &CLASS unpacked_load_raw)
+ maximum = 0xf790;
+ } else if (!strcmp(model,"E-3")) {
+ maximum = 0xf99;
+ goto e410;
+ } else if (!strcmp(model,"E-410") ||
+ !strcmp(model,"E-510")) {
+ maximum = 0xf6a;
+e410: load_raw = &CLASS olympus_e410_load_raw;
+ black >>= 4;
+ } else if (!strcmp(model,"SP550UZ")) {
+ thumb_length = fsize - (thumb_offset = 0xa39800);
+ thumb_height = 480;
+ thumb_width = 640;
+ }
+ } else if (!strcmp(model,"N Digital")) {
+ height = 2047;
+ width = 3072;
+ filters = 0x61616161;
+ data_offset = 0x1a00;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf1e;
+ } else if (!strcmp(model,"DSC-F828")) {
+ width = 3288;
+ left_margin = 5;
+ data_offset = 862144;
+ load_raw = &CLASS sony_load_raw;
+ filters = 0x9c9c9c9c;
+ colors = 4;
+ strcpy (cdesc, "RGBE");
+ } else if (!strcmp(model,"DSC-V3")) {
+ width = 3109;
+ left_margin = 59;
+ data_offset = 787392;
+ load_raw = &CLASS sony_load_raw;
+ } else if (!strcmp(make,"SONY") && raw_width == 3984) {
+ adobe_coeff ("SONY","DSC-R1");
+ width = 3925;
+ order = 0x4d4d;
+ } else if (!strcmp(model,"DSLR-A100")) {
+ height--;
+ load_raw = &CLASS sony_arw_load_raw;
+ maximum = 0xfeb;
+ } else if (!strncmp(model,"P850",4)) {
+ maximum = 0xf7c;
+ } else if (!strcmp(model,"C330")) {
+ height = 1744;
+ width = 2336;
+ raw_height = 1779;
+ raw_width = 2338;
+ top_margin = 33;
+ left_margin = 1;
+ order = 0x4949;
+ if ((data_offset = fsize - raw_height*raw_width)) {
+ fseek (ifp, 168, SEEK_SET);
+ read_shorts (curve, 256);
+ } else use_gamma = 0;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (!strcasecmp(make,"KODAK")) {
+ if (filters == UINT_MAX) filters = 0x61616161;
+ if (!strncmp(model,"NC2000",6)) {
+ width -= 4;
+ left_margin = 2;
+ } else if (!strcmp(model,"EOSDCS3B")) {
+ width -= 4;
+ left_margin = 2;
+ } else if (!strcmp(model,"EOSDCS1")) {
+ width -= 4;
+ left_margin = 2;
+ } else if (!strcmp(model,"DCS420")) {
+ width -= 4;
+ left_margin = 2;
+ } else if (!strcmp(model,"DCS460")) {
+ width -= 4;
+ left_margin = 2;
+ } else if (!strcmp(model,"DCS460A")) {
+ width -= 4;
+ left_margin = 2;
+ colors = 1;
+ filters = 0;
+ } else if (!strcmp(model,"DCS660M")) {
+ black = 214;
+ colors = 1;
+ filters = 0;
+ } else if (!strcmp(model,"DCS760M")) {
+ colors = 1;
+ filters = 0;
+ }
+ if (strstr(model,"DC25")) {
+ strcpy (model, "DC25");
+ data_offset = 15424;
+ }
+ if (!strncmp(model,"DC2",3)) {
+ height = 242;
+ if (fsize < 100000) {
+ raw_width = 256; width = 249;
+ pixel_aspect = (4.0*height) / (3.0*width);
+ } else {
+ raw_width = 512; width = 501;
+ pixel_aspect = (493.0*height) / (373.0*width);
+ }
+ data_offset += raw_width + 1;
+ colors = 4;
+ filters = 0x8d8d8d8d;
+ simple_coeff(1);
+ pre_mul[1] = 1.179;
+ pre_mul[2] = 1.209;
+ pre_mul[3] = 1.036;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (!strcmp(model,"40")) {
+ strcpy (model, "DC40");
+ height = 512;
+ width = 768;
+ data_offset = 1152;
+ load_raw = &CLASS kodak_radc_load_raw;
+ } else if (strstr(model,"DC50")) {
+ strcpy (model, "DC50");
+ height = 512;
+ width = 768;
+ data_offset = 19712;
+ load_raw = &CLASS kodak_radc_load_raw;
+ } else if (strstr(model,"DC120")) {
+ strcpy (model, "DC120");
+ height = 976;
+ width = 848;
+ pixel_aspect = height/0.75/width;
+ load_raw = tiff_compress == 7 ?
+ &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
+ } else if (!strcmp(model,"DCS200")) {
+ thumb_height = 128;
+ thumb_width = 192;
+ thumb_offset = 6144;
+ thumb_misc = 360;
+ write_thumb = &CLASS layer_thumb;
+ height = 1024;
+ width = 1536;
+ data_offset = 79872;
+ load_raw = &CLASS eight_bit_load_raw;
+ black = 17;
+ }
+ } else if (!strcmp(model,"Fotoman Pixtura")) {
+ height = 512;
+ width = 768;
+ data_offset = 3632;
+ load_raw = &CLASS kodak_radc_load_raw;
+ filters = 0x61616161;
+ simple_coeff(2);
+ } else if (!strcmp(model,"QuickTake 100")) {
+ data_offset = 736;
+ load_raw = &CLASS quicktake_100_load_raw;
+ goto qt_common;
+ } else if (!strcmp(model,"QuickTake 150")) {
+ data_offset = 738;
+ load_raw = &CLASS kodak_radc_load_raw;
+qt_common:
+ height = 480;
+ width = 640;
+ filters = 0x61616161;
+ } else if (!strcmp(make,"Rollei") && !load_raw) {
+ switch (raw_width) {
+ case 1316:
+ height = 1030;
+ width = 1300;
+ top_margin = 1;
+ left_margin = 6;
+ break;
+ case 2568:
+ height = 1960;
+ width = 2560;
+ top_margin = 2;
+ left_margin = 8;
+ }
+ filters = 0x16161616;
+ load_raw = &CLASS rollei_load_raw;
+ pre_mul[0] = 1.8;
+ pre_mul[2] = 1.3;
+ } else if (!strcmp(model,"PC-CAM 600")) {
+ height = 768;
+ data_offset = width = 1024;
+ filters = 0x49494949;
+ load_raw = &CLASS eight_bit_load_raw;
+ pre_mul[0] = 1.14;
+ pre_mul[2] = 2.73;
+ } else if (!strcmp(model,"QV-2000UX")) {
+ height = 1208;
+ width = 1632;
+ data_offset = width * 2;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (fsize == 3217760) {
+ height = 1546;
+ width = 2070;
+ raw_width = 2080;
+ load_raw = &CLASS eight_bit_load_raw;
+ } else if (!strcmp(model,"QV-4000")) {
+ height = 1700;
+ width = 2260;
+ load_raw = &CLASS unpacked_load_raw;
+ maximum = 0xffff;
+ } else if (!strcmp(model,"QV-5700")) {
+ height = 1924;
+ width = 2576;
+ load_raw = &CLASS casio_qv5700_load_raw;
+ } else if (!strcmp(model,"QV-R41")) {
+ height = 1720;
+ width = 2312;
+ raw_width = 3520;
+ left_margin = 2;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7f;
+ } else if (!strcmp(model,"QV-R51")) {
+ height = 1926;
+ width = 2580;
+ raw_width = 3904;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7f;
+ pre_mul[0] = 1.340;
+ pre_mul[2] = 1.672;
+ } else if (!strcmp(model,"EX-S100")) {
+ height = 1544;
+ width = 2058;
+ raw_width = 3136;
+ load_raw = &CLASS packed_12_load_raw;
+ pre_mul[0] = 1.631;
+ pre_mul[2] = 1.106;
+ } else if (!strcmp(model,"EX-Z50")) {
+ height = 1931;
+ width = 2570;
+ raw_width = 3904;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7f;
+ pre_mul[0] = 2.529;
+ pre_mul[2] = 1.185;
+ } else if (!strcmp(model,"EX-Z55")) {
+ height = 1960;
+ width = 2570;
+ raw_width = 3904;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7f;
+ pre_mul[0] = 1.520;
+ pre_mul[2] = 1.316;
+ } else if (!strcmp(model,"EX-P505")) {
+ height = 1928;
+ width = 2568;
+ raw_width = 3852;
+ load_raw = &CLASS packed_12_load_raw;
+ pre_mul[0] = 2.07;
+ pre_mul[2] = 1.88;
+ } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */
+ height = 2142;
+ width = 2844;
+ raw_width = 4288;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7f;
+ pre_mul[0] = 1.797;
+ pre_mul[2] = 1.219;
+ } else if (!strcmp(model,"EX-P700")) {
+ height = 2318;
+ width = 3082;
+ raw_width = 4672;
+ load_raw = &CLASS packed_12_load_raw;
+ maximum = 0xf7f;
+ pre_mul[0] = 1.758;
+ pre_mul[2] = 1.504;
+ }
+ if (!model[0])
+ sprintf (model, "%dx%d", width, height);
+ if (filters == UINT_MAX) filters = 0x94949494;
+ if (raw_color) adobe_coeff (make, model);
+ if (thumb_offset && !thumb_height) {
+ fseek (ifp, thumb_offset, SEEK_SET);
+ if (ljpeg_start (&jh, 1)) {
+ thumb_width = jh.wide;
+ thumb_height = jh.high;
+ }
+ }
+dng_skip:
+ if (!load_raw || height < 22) is_raw = 0;
+#ifdef NO_JPEG
+ if (load_raw == kodak_jpeg_load_raw) {
+ fprintf (stderr,_("%s: You must link dcraw with libjpeg!!\n"), ifname);
+ is_raw = 0;
+ }
+#endif
+ if (!cdesc[0])
+ strcpy (cdesc, colors == 3 ? "RGB":"GMCY");
+ if (!raw_height) raw_height = height;
+ if (!raw_width ) raw_width = width;
+ if (filters && colors == 3)
+ for (i=0; i < 32; i+=4) {
+ if ((filters >> i & 15) == 9)
+ filters |= 2 << i;
+ if ((filters >> i & 15) == 6)
+ filters |= 8 << i;
+ }
+notraw:
+ if (flip == -1) flip = tiff_flip;
+ if (flip == -1) flip = 0;
+}
+
+#ifndef NO_LCMS
+void CLASS apply_profile (char *input, char *output)
+{
+ char *prof;
+ cmsHPROFILE hInProfile=0, hOutProfile=0;
+ cmsHTRANSFORM hTransform;
+ FILE *fp;
+ unsigned size;
+
+ cmsErrorAction (LCMS_ERROR_SHOW);
+ if (strcmp (input, "embed"))
+ hInProfile = cmsOpenProfileFromFile (input, "r");
+ else if (profile_length) {
+ prof = (char *) malloc (profile_length);
+ merror (prof, "apply_profile()");
+ fseek (ifp, profile_offset, SEEK_SET);
+ fread (prof, 1, profile_length, ifp);
+ hInProfile = cmsOpenProfileFromMem (prof, profile_length);
+ free (prof);
+ } else
+ fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
+ if (!hInProfile) return;
+ if (!output)
+ hOutProfile = cmsCreate_sRGBProfile();
+ else if ((fp = fopen (output, "rb"))) {
+ fread (&size, 4, 1, fp);
+ fseek (fp, 0, SEEK_SET);
+ oprof = (unsigned *) malloc (size = ntohl(size));
+ merror (oprof, "apply_profile()");
+ fread (oprof, 1, size, fp);
+ fclose (fp);
+ if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
+ free (oprof);
+ oprof = 0;
+ }
+ } else
+ fprintf (stderr,_("Cannot open file %s!\n"), output);
+ if (!hOutProfile) goto quit;
+ if (verbose)
+ fprintf (stderr,_("Applying color profile...\n"));
+ hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
+ hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
+ cmsDoTransform (hTransform, image, image, width*height);
+ raw_color = 1; /* Don't use rgb_cam with a profile */
+ cmsDeleteTransform (hTransform);
+ cmsCloseProfile (hOutProfile);
+quit:
+ cmsCloseProfile (hInProfile);
+}
+#endif
+
+void CLASS convert_to_rgb()
+{
+ int row, col, c, i, j, k;
+ ushort *img;
+ float out[3], out_cam[3][4];
+ double num, inverse[3][3];
+ static const double xyzd50_srgb[3][3] =
+ { { 0.436083, 0.385083, 0.143055 },
+ { 0.222507, 0.716888, 0.060608 },
+ { 0.013930, 0.097097, 0.714022 } };
+ static const double rgb_rgb[3][3] =
+ { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
+ static const double adobe_rgb[3][3] =
+ { { 0.715146, 0.284856, 0.000000 },
+ { 0.000000, 1.000000, 0.000000 },
+ { 0.000000, 0.041166, 0.958839 } };
+ static const double wide_rgb[3][3] =
+ { { 0.593087, 0.404710, 0.002206 },
+ { 0.095413, 0.843149, 0.061439 },
+ { 0.011621, 0.069091, 0.919288 } };
+ static const double prophoto_rgb[3][3] =
+ { { 0.529317, 0.330092, 0.140588 },
+ { 0.098368, 0.873465, 0.028169 },
+ { 0.016879, 0.117663, 0.865457 } };
+ static const double (*out_rgb[])[3] =
+ { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
+ static const char *name[] =
+ { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" };
+ static const unsigned phead[] =
+ { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
+ 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
+ unsigned pbody[] =
+ { 10, 0x63707274, 0, 36, /* cprt */
+ 0x64657363, 0, 40, /* desc */
+ 0x77747074, 0, 20, /* wtpt */
+ 0x626b7074, 0, 20, /* bkpt */
+ 0x72545243, 0, 14, /* rTRC */
+ 0x67545243, 0, 14, /* gTRC */
+ 0x62545243, 0, 14, /* bTRC */
+ 0x7258595a, 0, 20, /* rXYZ */
+ 0x6758595a, 0, 20, /* gXYZ */
+ 0x6258595a, 0, 20 }; /* bXYZ */
+ static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
+ unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
+
+ memcpy (out_cam, rgb_cam, sizeof out_cam);
+ raw_color |= colors == 1 || document_mode ||
+ output_color < 1 || output_color > 5;
+ if (!raw_color) {
+ oprof = (unsigned *) calloc (phead[0], 1);
+ merror (oprof, "convert_to_rgb()");
+ memcpy (oprof, phead, sizeof phead);
+ if (output_color == 5) oprof[4] = oprof[5];
+ oprof[0] = 132 + 12*pbody[0];
+ for (i=0; i < pbody[0]; i++) {
+ oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
+ pbody[i*3+2] = oprof[0];
+ oprof[0] += (pbody[i*3+3] + 3) & -4;
+ }
+ memcpy (oprof+32, pbody, sizeof pbody);
+ oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
+ memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
+ if (output_bps == 8)
+#ifdef SRGB_GAMMA
+ pcurve[3] = 0x2330000;
+#else
+ pcurve[3] = 0x1f00000;
+#endif
+ for (i=4; i < 7; i++)
+ memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
+ pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
+ for (i=0; i < 3; i++)
+ for (j=0; j < 3; j++) {
+ for (num = k=0; k < 3; k++)
+ num += xyzd50_srgb[i][k] * inverse[j][k];
+ oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
+ }
+ for (i=0; i < phead[0]/4; i++)
+ oprof[i] = htonl(oprof[i]);
+ strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
+ strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
+ for (i=0; i < 3; i++)
+ for (j=0; j < colors; j++)
+ for (out_cam[i][j] = k=0; k < 3; k++)
+ out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
+ }
+ if (verbose)
+ fprintf (stderr, raw_color ? _("Building histograms...\n") :
+ _("Converting to %s colorspace...\n"), name[output_color-1]);
+
+ memset (histogram, 0, sizeof histogram);
+ for (img=image[0], row=0; row < height; row++)
+ for (col=0; col < width; col++, img+=4) {
+ if (!raw_color) {
+ out[0] = out[1] = out[2] = 0;
+ FORCC {
+ out[0] += out_cam[0][c] * img[c];
+ out[1] += out_cam[1][c] * img[c];
+ out[2] += out_cam[2][c] * img[c];
+ }
+ FORC3 img[c] = CLIP((int) out[c]);
+ }
+ else if (document_mode)
+ img[0] = img[FC(row,col)];
+ FORCC histogram[c][img[c] >> 3]++;
+ }
+ if (colors == 4 && output_color) colors = 3;
+ if (document_mode && filters) colors = 1;
+}
+
+void CLASS fuji_rotate()
+{
+ int i, row, col;
+ double step;
+ float r, c, fr, fc;
+ unsigned ur, uc;
+ ushort wide, high, (*img)[4], (*pix)[4];
+
+ if (!fuji_width) return;
+ if (verbose)
+ fprintf (stderr,_("Rotating image 45 degrees...\n"));
+ fuji_width = (fuji_width - 1 + shrink) >> shrink;
+ step = sqrt(0.5);
+ wide = fuji_width / step;
+ high = (height - fuji_width) / step;
+ img = (ushort (*)[4]) calloc (wide*high, sizeof *img);
+ merror (img, "fuji_rotate()");
+
+ for (row=0; row < high; row++)
+ for (col=0; col < wide; col++) {
+ ur = r = fuji_width + (row-col)*step;
+ uc = c = (row+col)*step;
+ if (ur > height-2 || uc > width-2) continue;
+ fr = r - ur;
+ fc = c - uc;
+ pix = image + ur*width + uc;
+ for (i=0; i < colors; i++)
+ img[row*wide+col][i] =
+ (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
+ (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
+ }
+ free (image);
+ width = wide;
+ height = high;
+ image = img;
+ fuji_width = 0;
+}
+
+void CLASS stretch()
+{
+ ushort newdim, (*img)[4], *pix0, *pix1;
+ int row, col, c;
+ double rc, frac;
+
+ if (pixel_aspect == 1) return;
+ if (verbose) fprintf (stderr,_("Stretching the image...\n"));
+ if (pixel_aspect < 1) {
+ newdim = height / pixel_aspect + 0.5;
+ img = (ushort (*)[4]) calloc (width*newdim, sizeof *img);
+ merror (img, "stretch()");
+ for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
+ frac = rc - (c = rc);
+ pix0 = pix1 = image[c*width];
+ if (c+1 < height) pix1 += width*4;
+ for (col=0; col < width; col++, pix0+=4, pix1+=4)
+ FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
+ }
+ height = newdim;
+ } else {
+ newdim = width * pixel_aspect + 0.5;
+ img = (ushort (*)[4]) calloc (height*newdim, sizeof *img);
+ merror (img, "stretch()");
+ for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
+ frac = rc - (c = rc);
+ pix0 = pix1 = image[c];
+ if (c+1 < width) pix1 += 4;
+ for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
+ FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
+ }
+ width = newdim;
+ }
+ free (image);
+ image = img;
+}
+
+int CLASS flip_index (int row, int col)
+{
+ if (flip & 4) SWAP(row,col);
+ if (flip & 2) row = iheight - 1 - row;
+ if (flip & 1) col = iwidth - 1 - col;
+ return row * iwidth + col;
+}
+
+void CLASS gamma_lut (uchar lut[0x10000])
+{
+ int perc, c, val, total, i;
+ float white=0, r;
+
+ perc = width * height * 0.01; /* 99th percentile white point */
+ if (fuji_width) perc /= 2;
+ if (highlight && highlight != 2) perc = -1;
+ FORCC {
+ for (val=0x2000, total=0; --val > 32; )
+ if ((total += histogram[c][val]) > perc) break;
+ if (white < val) white = val;
+ }
+ white *= 8 / bright;
+ for (i=0; i < 0x10000; i++) {
+ r = i / white;
+ val = 256 * ( !use_gamma ? r :
+#ifdef SRGB_GAMMA
+ r <= 0.00304 ? r*12.92 : pow(r,2.5/6)*1.055-0.055 );
+#else
+ r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099 );
+#endif
+ if (val > 255) val = 255;
+ lut[i] = val;
+ }
+}
+
+struct tiff_tag {
+ ushort tag, type;
+ int count;
+ union { short s0, s1; int i0; } val;
+};
+
+struct tiff_hdr {
+ ushort order, magic;
+ int ifd;
+ ushort pad, ntag;
+ struct tiff_tag tag[22];
+ int nextifd;
+ ushort pad2, nexif;
+ struct tiff_tag exif[4];
+ short bps[4];
+ int rat[10];
+ char desc[512], make[64], model[64], soft[32], date[20], artist[64];
+};
+
+void CLASS tiff_set (ushort *ntag,
+ ushort tag, ushort type, int count, int val)
+{
+ struct tiff_tag *tt;
+
+ tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
+ tt->tag = tag;
+ tt->type = type;
+ tt->count = count;
+ if (type == 3 && count == 1)
+ tt->val.s0 = val;
+ else tt->val.i0 = val;
+}
+
+#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
+
+void CLASS tiff_head (struct tiff_hdr *th, int full)
+{
+ int c, psize=0;
+ struct tm *t;
+
+ memset (th, 0, sizeof *th);
+ th->order = htonl(0x4d4d4949) >> 16;
+ th->magic = 42;
+ th->ifd = 10;
+ if (full) {
+ tiff_set (&th->ntag, 254, 4, 1, 0);
+ tiff_set (&th->ntag, 256, 4, 1, width);
+ tiff_set (&th->ntag, 257, 4, 1, height);
+ tiff_set (&th->ntag, 258, 3, colors, output_bps);
+ if (colors > 2)
+ th->tag[th->ntag-1].val.i0 = TOFF(th->bps);
+ FORC4 th->bps[c] = output_bps;
+ tiff_set (&th->ntag, 259, 3, 1, 1);
+ tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1));
+ }
+ tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc));
+ tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make));
+ tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
+ if (full) {
+ if (oprof) psize = ntohl(oprof[0]);
+ tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
+ tiff_set (&th->ntag, 277, 3, 1, colors);
+ tiff_set (&th->ntag, 278, 4, 1, height);
+ tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
+ } else
+ tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0');
+ tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[6]));
+ tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[8]));
+ tiff_set (&th->ntag, 284, 3, 1, 1);
+ tiff_set (&th->ntag, 296, 3, 1, 2);
+ tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
+ tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
+ tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
+ tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
+ if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
+ tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[0]));
+ tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[2]));
+ tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
+ tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[4]));
+ for (c=0; c < 6; c++) th->rat[c] = 1000000;
+ th->rat[0] *= shutter;
+ th->rat[2] *= aperture;
+ th->rat[4] *= focal_len;
+ th->rat[6] = th->rat[8] = 300;
+ th->rat[7] = th->rat[9] = 1;
+ strncpy (th->desc, desc, 512);
+ strncpy (th->make, make, 64);
+ strncpy (th->model, model, 64);
+ strcpy (th->soft, "dcraw v"VERSION);
+ t = gmtime (&timestamp);
+ sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
+ t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
+ strncpy (th->artist, artist, 64);
+}
+
+void CLASS jpeg_thumb (FILE *tfp)
+{
+ char *thumb;
+ ushort exif[5];
+ struct tiff_hdr th;
+
+ thumb = (char *) malloc (thumb_length);
+ merror (thumb, "jpeg_thumb()");
+ fread (thumb, 1, thumb_length, ifp);
+ fputc (0xff, tfp);
+ fputc (0xd8, tfp);
+ if (strcmp (thumb+6, "Exif")) {
+ memcpy (exif, "\xff\xe1 Exif\0\0", 10);
+ exif[1] = htons (8 + sizeof th);
+ fwrite (exif, 1, sizeof exif, tfp);
+ tiff_head (&th, 0);
+ fwrite (&th, 1, sizeof th, tfp);
+ }
+ fwrite (thumb+2, 1, thumb_length-2, tfp);
+ free (thumb);
+}
+
+void CLASS write_ppm_tiff (FILE *ofp)
+{
+ struct tiff_hdr th;
+ uchar *ppm, lut[0x10000];
+ ushort *ppm2;
+ int c, row, col, soff, rstep, cstep;
+
+ iheight = height;
+ iwidth = width;
+ if (flip & 4) SWAP(height,width);
+ ppm = (uchar *) calloc (width, colors*output_bps/8);
+ ppm2 = (ushort *) ppm;
+ merror (ppm, "write_ppm_tiff()");
+ if (output_tiff) {
+ tiff_head (&th, 1);
+ fwrite (&th, sizeof th, 1, ofp);
+ if (oprof)
+ fwrite (oprof, ntohl(oprof[0]), 1, ofp);
+ } else if (colors > 3)
+ fprintf (ofp,
+ "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
+ width, height, colors, (1 << output_bps)-1, cdesc);
+ else
+ fprintf (ofp, "P%d\n%d %d\n%d\n",
+ colors/2+5, width, height, (1 << output_bps)-1);
+
+ if (output_bps == 8) gamma_lut (lut);
+ soff = flip_index (0, 0);
+ cstep = flip_index (0, 1) - soff;
+ rstep = flip_index (1, 0) - flip_index (0, width);
+ for (row=0; row < height; row++, soff += rstep) {
+ for (col=0; col < width; col++, soff += cstep)
+ if (output_bps == 8)
+ FORCC ppm [col*colors+c] = lut[image[soff][c]];
+ else FORCC ppm2[col*colors+c] = image[soff][c];
+ if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
+ swab (ppm2, ppm2, width*colors*2);
+ fwrite (ppm, colors*output_bps/8, width, ofp);
+ }
+ free (ppm);
+}
+
+int CLASS main (int argc, char **argv)
+{
+ int arg, status=0, user_flip=-1, user_black=-1, user_qual=-1;
+ int timestamp_only=0, thumbnail_only=0, identify_only=0;
+ int use_fuji_rotate=1, write_to_stdout=0, quality, i, c;
+ char opm, opt, *ofname, *sp, *cp, *dark_frame=0;
+ const char *write_ext;
+ struct utimbuf ut;
+ FILE *ofp;
+#ifndef NO_LCMS
+ char *cam_profile=0, *out_profile=0;
+#endif
+
+#ifndef LOCALTIME
+ putenv ("TZ=UTC");
+#endif
+#ifdef LOCALEDIR
+ setlocale (LC_CTYPE, "");
+ setlocale (LC_MESSAGES, "");
+ bindtextdomain ("dcraw", LOCALEDIR);
+ textdomain ("dcraw");
+#endif
+
+ if (argc == 1) {
+ printf(_("\nRaw photo decoder \"dcraw\" v%s"), VERSION);
+ printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
+ printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
+ puts(_("-v Print verbose messages"));
+ puts(_("-c Write image data to standard output"));
+ puts(_("-e Extract embedded thumbnail image"));
+ puts(_("-i Identify files without decoding them"));
+ puts(_("-i -v Identify files and show metadata"));
+ puts(_("-z Change file dates to camera timestamp"));
+ puts(_("-w Use camera white balance, if possible"));
+ puts(_("-a Average the whole image for white balance"));
+ puts(_("-A <x y w h> Average a grey box for white balance"));
+ puts(_("-r <r g b g> Set custom white balance"));
+ puts(_("+M/-M Use/don't use an embedded color matrix"));
+ puts(_("-C <r b> Correct chromatic aberration"));
+ puts(_("-b <num> Adjust brightness (default = 1.0)"));
+ puts(_("-n <num> Set threshold for wavelet denoising"));
+ puts(_("-k <num> Set black point"));
+ puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
+ puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
+ puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
+ puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"));
+#ifndef NO_LCMS
+ puts(_("-o <file> Apply output ICC profile from file"));
+ puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
+#endif
+ puts(_("-d Document mode (no color, no interpolation)"));
+ puts(_("-D Document mode without scaling (totally raw)"));
+ puts(_("-j Don't stretch or rotate raw pixels"));
+ puts(_("-q [0-3] Set the interpolation quality"));
+ puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
+ puts(_("-f Interpolate RGGB as four colors"));
+ puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
+ puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
+ puts(_("-4 Write 16-bit linear instead of 8-bit with gamma"));
+ puts(_("-T Write TIFF instead of PPM"));
+ puts("");
+ return 1;
+ }
+ argv[argc] = "";
+ for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
+ opt = argv[arg++][1];
+ if ((cp = strchr (sp="nbrktqmHAC", opt)))
+ for (i=0; i < "1141111142"[cp-sp]-'0'; i++)
+ if (!isdigit(argv[arg+i][0])) {
+ fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
+ return 1;
+ }
+ switch (opt) {
+ case 'n': threshold = atof(argv[arg++]); break;
+ case 'b': bright = atof(argv[arg++]); break;
+ case 'r':
+ FORC4 user_mul[c] = atof(argv[arg++]); break;
+ case 'C': aber[0] = 1 / atof(argv[arg++]);
+ aber[2] = 1 / atof(argv[arg++]); break;
+ case 'k': user_black = atoi(argv[arg++]); break;
+ case 't': user_flip = atoi(argv[arg++]); break;
+ case 'q': user_qual = atoi(argv[arg++]); break;
+ case 'm': med_passes = atoi(argv[arg++]); break;
+ case 'H': highlight = atoi(argv[arg++]); break;
+ case 's':
+ shot_select = abs(atoi(argv[arg]));
+ multi_out = !strcmp(argv[arg++],"all");
+ break;
+ case 'o':
+ if (isdigit(argv[arg][0]) && !argv[arg][1])
+ output_color = atoi(argv[arg++]);
+#ifndef NO_LCMS
+ else out_profile = argv[arg++];
+ break;
+ case 'p': cam_profile = argv[arg++];
+#endif
+ break;
+ case 'K': dark_frame = argv[arg++];
+ break;
+ case 'z': timestamp_only = 1; break;
+ case 'e': thumbnail_only = 1; break;
+ case 'i': identify_only = 1; break;
+ case 'c': write_to_stdout = 1; break;
+ case 'v': verbose = 1; break;
+ case 'h': half_size = 1; /* "-h" implies "-f" */
+ case 'f': four_color_rgb = 1; break;
+ case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
+ case 'a': use_auto_wb = 1; break;
+ case 'w': use_camera_wb = 1; break;
+ case 'M': use_camera_matrix = (opm == '+'); break;
+ case 'D':
+ case 'd': document_mode = 1 + (opt == 'D');
+ case 'j': use_fuji_rotate = 0; break;
+ case 'T': output_tiff = 1; break;
+ case '4': output_bps = 16; break;
+ default:
+ fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
+ return 1;
+ }
+ }
+ if (use_camera_matrix < 0)
+ use_camera_matrix = use_camera_wb;
+ if (arg == argc) {
+ fprintf (stderr,_("No files to process.\n"));
+ return 1;
+ }
+ if (write_to_stdout) {
+ if (isatty(1)) {
+ fprintf (stderr,_("Will not write an image to the terminal!\n"));
+ return 1;
+ }
+#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
+ if (setmode(1,O_BINARY) < 0) {
+ perror ("setmode()");
+ return 1;
+ }
+#endif
+ }
+ for ( ; arg < argc; arg++) {
+ status = 1;
+ image = 0;
+ oprof = 0;
+ meta_data = ofname = 0;
+ ofp = stdout;
+ if (setjmp (failure)) {
+ if (fileno(ifp) > 2) fclose(ifp);
+ if (fileno(ofp) > 2) fclose(ofp);
+ status = 1;
+ goto cleanup;
+ }
+ ifname = argv[arg];
+ if (!(ifp = fopen (ifname, "rb"))) {
+ perror (ifname);
+ continue;
+ }
+ status = (identify(),!is_raw);
+ if (user_flip >= 0)
+ flip = user_flip;
+ switch ((flip+3600) % 360) {
+ case 270: flip = 5; break;
+ case 180: flip = 3; break;
+ case 90: flip = 6;
+ }
+ if (timestamp_only) {
+ if ((status = !timestamp))
+ fprintf (stderr,_("%s has no timestamp.\n"), ifname);
+ else if (identify_only)
+ printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
+ else {
+ if (verbose)
+ fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
+ ut.actime = ut.modtime = timestamp;
+ utime (ifname, &ut);
+ }
+ goto next;
+ }
+ write_fun = &CLASS write_ppm_tiff;
+ if (thumbnail_only) {
+ if ((status = !thumb_offset)) {
+ fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
+ goto next;
+ } else if (thumb_load_raw) {
+ load_raw = thumb_load_raw;
+ data_offset = thumb_offset;
+ height = thumb_height;
+ width = thumb_width;
+ filters = 0;
+ } else {
+ fseek (ifp, thumb_offset, SEEK_SET);
+ write_fun = write_thumb;
+ goto thumbnail;
+ }
+ }
+ if (load_raw == &CLASS kodak_ycbcr_load_raw) {
+ height += height & 1;
+ width += width & 1;
+ }
+ if (identify_only && verbose && make[0]) {
+ printf (_("\nFilename: %s\n"), ifname);
+ printf (_("Timestamp: %s"), ctime(&timestamp));
+ printf (_("Camera: %s %s\n"), make, model);
+ if (artist[0])
+ printf (_("Owner: %s\n"), artist);
+ if (dng_version) {
+ printf (_("DNG Version: "));
+ for (i=24; i >= 0; i -= 8)
+ printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
+ }
+ printf (_("ISO speed: %d\n"), (int) iso_speed);
+ printf (_("Shutter: "));
+ if (shutter > 0 && shutter < 1)
+ shutter = (printf ("1/"), 1 / shutter);
+ printf (_("%0.1f sec\n"), shutter);
+ printf (_("Aperture: f/%0.1f\n"), aperture);
+ printf (_("Focal length: %0.1f mm\n"), focal_len);
+ printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
+ printf (_("Number of raw images: %d\n"), is_raw);
+ if (pixel_aspect != 1)
+ printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
+ if (thumb_offset)
+ printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
+ printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
+ } else if (!is_raw)
+ fprintf (stderr,_("Cannot decode file %s\n"), ifname);
+ if (!is_raw) goto next;
+ shrink = filters &&
+ (half_size || threshold || aber[0] != 1 || aber[2] != 1);
+ iheight = (height + shrink) >> shrink;
+ iwidth = (width + shrink) >> shrink;
+ if (identify_only) {
+ if (verbose) {
+ if (use_fuji_rotate) {
+ if (fuji_width) {
+ fuji_width = (fuji_width - 1 + shrink) >> shrink;
+ iwidth = fuji_width / sqrt(0.5);
+ iheight = (iheight - fuji_width) / sqrt(0.5);
+ } else {
+ if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
+ if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
+ }
+ }
+ if (flip & 4)
+ SWAP(iheight,iwidth);
+ printf (_("Image size: %4d x %d\n"), width, height);
+ printf (_("Output size: %4d x %d\n"), iwidth, iheight);
+ printf (_("Raw colors: %d"), colors);
+ if (filters) {
+ printf (_("\nFilter pattern: "));
+ if (!cdesc[3]) cdesc[3] = 'G';
+ for (i=0; i < 16; i++)
+ putchar (cdesc[fc(i >> 1,i & 1)]);
+ }
+ printf (_("\nDaylight multipliers:"));
+ FORCC printf (" %f", pre_mul[c]);
+ if (cam_mul[0] > 0) {
+ printf (_("\nCamera multipliers:"));
+ FORC4 printf (" %f", cam_mul[c]);
+ }
+ putchar ('\n');
+ } else
+ printf (_("%s is a %s %s image.\n"), ifname, make, model);
+next:
+ fclose(ifp);
+ continue;
+ }
+ if (use_camera_matrix && cmatrix[0][0] > 0.25) {
+ memcpy (rgb_cam, cmatrix, sizeof cmatrix);
+ raw_color = 0;
+ }
+ image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
+ merror (image, "main()");
+ if (meta_length) {
+ meta_data = (char *) malloc (meta_length);
+ merror (meta_data, "main()");
+ }
+ if (verbose)
+ fprintf (stderr,_("Loading %s %s image from %s ...\n"),
+ make, model, ifname);
+ if (shot_select >= is_raw)
+ fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
+ ifname, shot_select);
+ fseeko (ifp, data_offset, SEEK_SET);
+ (*load_raw)();
+ if (zero_is_bad) remove_zeroes();
+ bad_pixels();
+ if (dark_frame) subtract (dark_frame);
+ quality = 2 + !fuji_width;
+ if (user_qual >= 0) quality = user_qual;
+ if (user_black >= 0) black = user_black;
+#ifdef COLORCHECK
+ colorcheck();
+#endif
+ if (is_foveon && !document_mode) foveon_interpolate();
+ if (!is_foveon && document_mode < 2) scale_colors();
+ pre_interpolate();
+ if (filters && !document_mode) {
+ if (quality == 0)
+ lin_interpolate();
+ else if (quality == 1 || colors > 3)
+ vng_interpolate();
+ else if (quality == 2)
+ ppg_interpolate();
+ else ahd_interpolate();
+ }
+ if (mix_green)
+ for (colors=3, i=0; i < height*width; i++)
+ image[i][1] = (image[i][1] + image[i][3]) >> 1;
+ if (!is_foveon && colors == 3) median_filter();
+ if (!is_foveon && highlight == 2) blend_highlights();
+ if (!is_foveon && highlight > 2) recover_highlights();
+ if (use_fuji_rotate) fuji_rotate();
+#ifndef NO_LCMS
+ if (cam_profile) apply_profile (cam_profile, out_profile);
+#endif
+ convert_to_rgb();
+ if (use_fuji_rotate) stretch();
+thumbnail:
+ if (write_fun == &CLASS jpeg_thumb)
+ write_ext = ".jpg";
+ else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
+ write_ext = ".tiff";
+ else
+ write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
+ ofname = (char *) malloc (strlen(ifname) + 64);
+ merror (ofname, "main()");
+ if (write_to_stdout)
+ strcpy (ofname,_("standard output"));
+ else {
+ strcpy (ofname, ifname);
+ if ((cp = strrchr (ofname, '.'))) *cp = 0;
+ if (multi_out)
+ sprintf (ofname+strlen(ofname), "_%0*d",
+ snprintf(0,0,"%d",is_raw-1), shot_select);
+ if (thumbnail_only)
+ strcat (ofname, ".thumb");
+ strcat (ofname, write_ext);
+ ofp = fopen (ofname, "wb");
+ if (!ofp) {
+ status = 1;
+ perror (ofname);
+ goto cleanup;
+ }
+ }
+ if (verbose)
+ fprintf (stderr,_("Writing data to %s ...\n"), ofname);
+ (*write_fun)(ofp);
+ fclose(ifp);
+ if (ofp != stdout) fclose(ofp);
+cleanup:
+ if (meta_data) free (meta_data);
+ if (ofname) free (ofname);
+ if (oprof) free (oprof);
+ if (image) free (image);
+ if (multi_out) {
+ if (++shot_select < is_raw) arg--;
+ else shot_select = 0;
+ }
+ }
+ return status;
+}
diff --git a/kernel/kls_camera/fmt_codec_pnm.cpp b/kernel/kls_camera/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_camera/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_camera/fmt_codec_pnm_defs.h b/kernel/kls_camera/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_camera/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_camera/ksquirrel-libs-camera2ppm.in b/kernel/kls_camera/ksquirrel-libs-camera2ppm.in
new file mode 100644
index 0000000..5ee4063
--- /dev/null
+++ b/kernel/kls_camera/ksquirrel-libs-camera2ppm.in
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+kls_camera_i=""
+kls_camera_o=""
+kls_camera_bin=""
+kls_camera_params=""
+
+while [ "$1" ] ; do
+
+ case "$1" in
+ "--input") kls_camera_i="$2" shift ;;
+ "--output") kls_camera_o="$2" shift ;;
+ "--binary") kls_camera_bin="$2" shift ;;
+ *) kls_camera_params="$kls_camera_params $1" ;;
+ esac
+
+shift
+done
+
+$kls_camera_bin $kls_camera_params "$kls_camera_i" > "$kls_camera_o" \ No newline at end of file
diff --git a/kernel/kls_camera/libkls_camera.so.ui b/kernel/kls_camera/libkls_camera.so.ui
new file mode 100644
index 0000000..645f30b
--- /dev/null
+++ b/kernel/kls_camera/libkls_camera.so.ui
@@ -0,0 +1,1023 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Form1</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>635</width>
+ <height>551</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>camera_white</cstring>
+ </property>
+ <property name="text">
+ <string>Use camera white balance, if possible</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="0">
+ <property name="name">
+ <cstring>interpolate_rggb</cstring>
+ </property>
+ <property name="text">
+ <string>Interpolate RGGB as four colors</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="6" column="0">
+ <property name="name">
+ <cstring>dontstretch</cstring>
+ </property>
+ <property name="text">
+ <string>Don't stretch or rotate raw pixels</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="0">
+ <property name="name">
+ <cstring>camera_date</cstring>
+ </property>
+ <property name="text">
+ <string>Change file dates to camera timestamp</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="7" column="0">
+ <property name="name">
+ <cstring>icc_cam</cstring>
+ </property>
+ <property name="text">
+ <string>Try to use the ICC profile embedded in the photo</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>half_size</cstring>
+ </property>
+ <property name="text">
+ <string>Half-size color image</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>automatic_white</cstring>
+ </property>
+ <property name="text">
+ <string>Use automatic white balance</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>document_mode</cstring>
+ </property>
+ <property name="text">
+ <string>Document mode (no color, no interpolation)</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1_4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>no_black</cstring>
+ </property>
+ <property name="specialValueText">
+ <string>no</string>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="minValue">
+ <number>-1</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel2_5</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Set black point&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider" row="2" column="0">
+ <property name="name">
+ <cstring>black</cstring>
+ </property>
+ <property name="minValue">
+ <number>-1</number>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>brightness</cstring>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QSlider" row="2" column="0">
+ <property name="name">
+ <cstring>no_brightness</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Adjust brightness&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="6" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>no_different</cstring>
+ </property>
+ <property name="prefix">
+ <string>#</string>
+ </property>
+ <property name="maxValue">
+ <number>99</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1_3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSlider" row="2" column="0">
+ <property name="name">
+ <cstring>different</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>99</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>5</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel2_4</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Select a different raw image from the same file&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="9" column="1">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSlider" row="2" column="0">
+ <property name="name">
+ <cstring>threshold</cstring>
+ </property>
+ <property name="minValue">
+ <number>99</number>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>99</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>75</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>no_threshold</cstring>
+ </property>
+ <property name="specialValueText">
+ <string>no</string>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="minValue">
+ <number>99</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Threshold for wavelet denoising&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1_2_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="10" column="1">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSlider" row="2" column="0">
+ <property name="name">
+ <cstring>highlights</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>no_highlights</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1_2_2_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QWidgetStack" row="3" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>no_widgetStack</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Clip all highlights to solid white</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>1</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Leave highlights unclipped in various shades of pink</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>2</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;favor whites 1&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>3</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;&lt;font color="magenta"&gt;favor whites 2&lt;/font&gt;&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>4</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3_3</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;&lt;font color="red"&gt;favor whites 3&lt;/font&gt;&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>5</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3_4</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;compromise&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>6</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;favor colors 1&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>7</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;&lt;font color="green"&gt;favor colors 2&lt;/font&gt;&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>8</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4_3</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;&lt;font color="magenta"&gt;favor colors 3&lt;/font&gt;&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>9</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4_4</cstring>
+ </property>
+ <property name="text">
+ <string>Reconstruct highlights: &lt;b&gt;&lt;font color="red"&gt;favor colors 4&lt;/font&gt;&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Highlights&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="10" column="0">
+ <property name="name">
+ <cstring>quick</cstring>
+ </property>
+ <property name="title">
+ <string>Interpolation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>1</number>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>radioButton1</cstring>
+ </property>
+ <property name="text">
+ <string>No interpolation</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>radioButton2</cstring>
+ </property>
+ <property name="text">
+ <string>Low-quality bilinear interpolation</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="2" column="0">
+ <property name="name">
+ <cstring>radioButton3</cstring>
+ </property>
+ <property name="text">
+ <string>Variable Number of Gradients interpolation</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="0">
+ <property name="name">
+ <cstring>radioButton4</cstring>
+ </property>
+ <property name="text">
+ <string>Adaptive Homogeneity-Directed interpolation</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="9" column="0">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Apply camera ICC profile from file&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>icc_file</cstring>
+ </property>
+ <property name="filter">
+ <string>*.icc *.icm</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QButtonGroup" row="11" column="0">
+ <property name="name">
+ <cstring>flipping</cstring>
+ </property>
+ <property name="title">
+ <string>Flipping</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>1</number>
+ </property>
+ <widget class="QRadioButton" row="3" column="0">
+ <property name="name">
+ <cstring>radioButton7</cstring>
+ </property>
+ <property name="text">
+ <string>90CCW</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>5</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="2" column="0">
+ <property name="name">
+ <cstring>radioButton6</cstring>
+ </property>
+ <property name="text">
+ <string>180</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>3</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>radioButton5</cstring>
+ </property>
+ <property name="text">
+ <string>None</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>radioButton9</cstring>
+ </property>
+ <property name="text">
+ <string>Camera settings</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="4" column="0">
+ <property name="name">
+ <cstring>radioButton8</cstring>
+ </property>
+ <property name="text">
+ <string>90CW</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>6</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="8" column="0">
+ <property name="name">
+ <cstring>embedded_cm</cstring>
+ </property>
+ <property name="text">
+ <string>Use an embedded color matrix</string>
+ </property>
+ </widget>
+ <spacer row="11" column="1">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>110</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>no_brightness</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>brightness</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>brightness</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_brightness</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>different</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_different</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_different</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>different</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>black</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_black</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_black</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>black</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>threshold</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_threshold</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_threshold</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>threshold</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>highlights</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_highlights</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_highlights</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>highlights</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>highlights</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_widgetStack</receiver>
+ <slot>raiseWidget(int)</slot>
+ </connection>
+ <connection>
+ <sender>icc_cam</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>icc_file</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>automatic_white</tabstop>
+ <tabstop>camera_white</tabstop>
+ <tabstop>document_mode</tabstop>
+ <tabstop>half_size</tabstop>
+ <tabstop>interpolate_rggb</tabstop>
+ <tabstop>camera_date</tabstop>
+ <tabstop>dontstretch</tabstop>
+ <tabstop>black</tabstop>
+ <tabstop>no_black</tabstop>
+ <tabstop>threshold</tabstop>
+ <tabstop>no_brightness</tabstop>
+ <tabstop>brightness</tabstop>
+ <tabstop>different</tabstop>
+ <tabstop>no_different</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kernel/kls_cut/Makefile.am b/kernel/kls_cut/Makefile.am
new file mode 100644
index 0000000..1137f5a
--- /dev/null
+++ b/kernel/kls_cut/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_cut.la
+
+libkls_cut_la_SOURCES = fmt_codec_cut.cpp fmt_codec_cut_defs.h
+
+libkls_cut_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_cut_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_cut/fmt_codec_cut.cpp b/kernel/kls_cut/fmt_codec_cut.cpp
new file mode 100644
index 0000000..803c4e4
--- /dev/null
+++ b/kernel/kls_cut/fmt_codec_cut.cpp
@@ -0,0 +1,173 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_cut_defs.h"
+#include "fmt_codec_cut.h"
+
+#include "../xpm/codec_cut.xpm"
+
+/*
+ *
+ * The Dr. Halo file format is a device-independent interchange format used for
+ * transporting image data from one hardware environment or operating system to
+ * another. This format is associated with the HALO Image File Format
+ * Library.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{
+ for(s32 i = 0;i < 256;i++)
+ memset(pal+i, i, sizeof(RGB));
+}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.1";
+ o->name = "Dr. Halo CUT";
+ o->filter = "*.cut ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-cut";
+ o->pixmap = codec_cut;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ s16 width, height;
+ s32 dummy;
+
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.readK(&width, sizeof(s16))) return SQE_R_BADFILE;
+ if(!frs.readK(&height, sizeof(s16))) return SQE_R_BADFILE;
+ if(!frs.readK(&dummy, sizeof(s32))) return SQE_R_BADFILE;
+
+ image.w = width;
+ image.h = height;
+ image.bpp = 8;
+
+ image.compression = "RLE";
+ image.colorspace = "Color indexed";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ s32 i = 0, j;
+ u8 count, run, c;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ while(i < im->w)
+ {
+ if(!frs.readK(&count, 1)) return SQE_R_BADFILE;
+
+ if(count == 0)
+ {
+ frs.readK(&c, 1);
+
+ if(!frs.readK(&c, 1)) return SQE_R_BADFILE;
+
+ continue; // ugly hack
+ }
+ else if(count & 0x80)
+ {
+ count &= ~(0x80);
+
+ if(!frs.readK(&run, 1)) return SQE_R_BADFILE;
+
+ for(j = 0;j < count;j++)
+ {
+ memcpy(scan+i, pal+run, sizeof(RGB));
+ i++;
+ }
+ }
+ else
+ {
+ for(j = 0;j < count;j++)
+ {
+ if(!frs.readK(&run, 1)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, pal+run, sizeof(RGB));
+
+ i++;
+ }
+ }
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_cut/fmt_codec_cut_defs.h b/kernel/kls_cut/fmt_codec_cut_defs.h
new file mode 100644
index 0000000..3caac6e
--- /dev/null
+++ b/kernel/kls_cut/fmt_codec_cut_defs.h
@@ -0,0 +1,25 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_cut
+#define KSQUIRREL_READ_IMAGE_cut
+
+#endif
diff --git a/kernel/kls_dds/Makefile.am b/kernel/kls_dds/Makefile.am
new file mode 100644
index 0000000..753dfb6
--- /dev/null
+++ b/kernel/kls_dds/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_dds.la
+
+libkls_dds_la_SOURCES = fmt_codec_dds.cpp fmt_codec_dds_defs.h dds.cpp
+
+libkls_dds_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_dds_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_dds/dds.cpp b/kernel/kls_dds/dds.cpp
new file mode 100644
index 0000000..c5551f0
--- /dev/null
+++ b/kernel/kls_dds/dds.cpp
@@ -0,0 +1,1066 @@
+/*
+ * (C) 2007 Dmitry Baryshev, KSquirrel project
+ */
+
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ignacio Casta�o <castano@ludicon.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the Lesser GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ Almost all this code is based on nVidia's DDS-loading example
+ and the DevIl's source code by Denton Woods.
+*/
+
+/* this code supports:
+ * reading:
+ * rgb and dxt dds files
+ * cubemap dds files
+ * volume dds files -- TODO
+ * writing:
+ * rgb dds files only -- TODO
+ */
+
+#include <cmath> // sqrtf
+#include <fstream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_defs.h"
+
+#include "dds.h"
+
+#ifndef __USE_ISOC99
+#define sqrtf(x) ((float)sqrt(x))
+#endif
+
+typedef u32 uint;
+typedef u16 ushort;
+typedef u8 uchar;
+
+typedef RGBA* RGBAP;
+
+namespace { // Private.
+
+static bool MALLOC_ROWS(RGBAP **A, const int RB, const int H)
+{
+ *A = (RGBAP *)malloc(H * sizeof(RGBA*));
+
+ if(!*A)
+ return false;
+
+ for(s32 row = 0; row < H; row++)
+ (*A)[row] = 0;
+
+ for(s32 row = 0; row < (s32)H; row++)
+ {
+ (*A)[row] = (RGBA *)malloc(RB);
+
+ if(!(*A)[row])
+ return false;
+
+ memset((*A)[row], 0, RB);
+ }
+
+ return true;
+}
+/*
+static void FREE_ROWS(RGBAP **A, const int H)
+{
+ if(*A)
+ {
+ for(s32 i = 0;i < H;i++)
+ {
+ if((*A)[i])
+ free((*A)[i]);
+ }
+
+ free(*A);
+ *A = 0;
+ }
+}
+*/
+#if !defined(MAKEFOURCC)
+# define MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ (uint(uchar(ch0)) | (uint(uchar(ch1)) << 8) | \
+ (uint(uchar(ch2)) << 16) | (uint(uchar(ch3)) << 24 ))
+#endif
+
+//#ifdef max
+#undef max
+#define max(a,b) ((a)>(b)?(a):(b))
+//#endif
+
+#define HORIZONTAL 1
+#define VERTICAL 2
+#define CUBE_LAYOUT HORIZONTAL
+
+ struct Color8888
+ {
+ uchar r, g, b, a;
+ };
+
+ union Color565
+ {
+ struct {
+ ushort b : 5;
+ ushort g : 6;
+ ushort r : 5;
+ } c;
+ ushort u;
+ };
+
+ union Color1555 {
+ struct {
+ ushort b : 5;
+ ushort g : 5;
+ ushort r : 5;
+ ushort a : 1;
+ } c;
+ ushort u;
+ };
+
+ union Color4444 {
+ struct {
+ ushort b : 4;
+ ushort g : 4;
+ ushort r : 4;
+ ushort a : 4;
+ } c;
+ ushort u;
+ };
+
+
+ static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
+ static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
+ static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
+ static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
+ static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
+ static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
+ static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B');
+ static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
+
+ static const uint DDSD_CAPS = 0x00000001l;
+ static const uint DDSD_PIXELFORMAT = 0x00001000l;
+ static const uint DDSD_WIDTH = 0x00000004l;
+ static const uint DDSD_HEIGHT = 0x00000002l;
+ static const uint DDSD_PITCH = 0x00000008l;
+
+ static const uint DDSCAPS_TEXTURE = 0x00001000l;
+ static const uint DDSCAPS2_VOLUME = 0x00200000l;
+ static const uint DDSCAPS2_CUBEMAP = 0x00000200l;
+
+ static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400l;
+ static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800l;
+ static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000l;
+ static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000l;
+ static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000l;
+ static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000l;
+
+ static const uint DDPF_RGB = 0x00000040l;
+ static const uint DDPF_FOURCC = 0x00000004l;
+ static const uint DDPF_ALPHAPIXELS = 0x00000001l;
+
+ enum DDSType {
+ DDS_A8R8G8B8 = 0,
+ DDS_A1R5G5B5 = 1,
+ DDS_A4R4G4B4 = 2,
+ DDS_R8G8B8 = 3,
+ DDS_R5G6B5 = 4,
+ DDS_DXT1 = 5,
+ DDS_DXT2 = 6,
+ DDS_DXT3 = 7,
+ DDS_DXT4 = 8,
+ DDS_DXT5 = 9,
+ DDS_RXGB = 10,
+ DDS_ATI2 = 11,
+ DDS_UNKNOWN
+ };
+
+
+ struct DDSPixelFormat {
+ uint size;
+ uint flags;
+ uint fourcc;
+ uint bitcount;
+ uint rmask;
+ uint gmask;
+ uint bmask;
+ uint amask;
+ };
+
+ static ifstreamK & operator>> ( ifstreamK & s, DDSPixelFormat & pf )
+ {
+ s.readK(&pf.size, sizeof(pf.size));
+ s.readK(&pf.flags, sizeof(pf.flags));
+ s.readK(&pf.fourcc, sizeof(pf.fourcc));
+ s.readK(&pf.bitcount, sizeof(pf.bitcount));
+ s.readK(&pf.rmask, sizeof(pf.rmask));
+ s.readK(&pf.gmask, sizeof(pf.gmask));
+ s.readK(&pf.bmask, sizeof(pf.bmask));
+ s.readK(&pf.amask, sizeof(pf.amask));
+
+ return s;
+ }
+
+ struct DDSCaps {
+ uint caps1;
+ uint caps2;
+ uint caps3;
+ uint caps4;
+ };
+
+ static ifstreamK & operator>> ( ifstreamK & s, DDSCaps & caps )
+ {
+ s.readK(&caps.caps1, sizeof(caps.caps1));
+ s.readK(&caps.caps2, sizeof(caps.caps2));
+ s.readK(&caps.caps3, sizeof(caps.caps3));
+ s.readK(&caps.caps4, sizeof(caps.caps4));
+
+ return s;
+ }
+
+ struct DDSHeader {
+ uint size;
+ uint flags;
+ uint height;
+ uint width;
+ uint pitch;
+ uint depth;
+ uint mipmapcount;
+ uint reserved[11];
+ DDSPixelFormat pf;
+ DDSCaps caps;
+ uint notused;
+ };
+
+ static ifstreamK & operator>> ( ifstreamK & s, DDSHeader & header )
+ {
+ s.readK(&header.size, sizeof(header.size));
+ s.readK(&header.flags, sizeof(header.flags));
+ s.readK(&header.height, sizeof(header.height));
+ s.readK(&header.width, sizeof(header.width));
+ s.readK(&header.pitch, sizeof(header.pitch));
+ s.readK(&header.depth, sizeof(header.depth));
+ s.readK(&header.mipmapcount, sizeof(header.mipmapcount));
+
+ for( int i = 0; i < 11; i++ )
+ {
+ s.readK(&header.reserved[i], sizeof(header.reserved[i]));
+ }
+
+ s >> header.pf;
+ s >> header.caps;
+
+ s.readK(&header.notused, sizeof(header.notused));
+
+ return s;
+ }
+
+ static bool IsValid( const DDSHeader & header )
+ {
+ if( header.size != 124 || !header.width || !header.height) {
+ return false;
+ }
+
+ const uint required = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT);
+
+ if( (header.flags & required) != required ) {
+ return false;
+ }
+ if( header.pf.size != 32 ) {
+ return false;
+ }
+ if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) {
+ return false;
+ }
+ return true;
+ }
+
+ // Get supported type. We currently support 10 different types.
+ static DDSType GetType( const DDSHeader & header )
+ {
+ if( header.pf.flags & DDPF_RGB ) {
+ if( header.pf.flags & DDPF_ALPHAPIXELS ) {
+ switch( header.pf.bitcount ) {
+ case 16:
+ return (header.pf.amask == 0x7000) ? DDS_A1R5G5B5 : DDS_A4R4G4B4;
+ case 32:
+ return DDS_A8R8G8B8;
+ }
+ }
+ else {
+ switch( header.pf.bitcount ) {
+ case 16:
+ return DDS_R5G6B5;
+ case 24:
+ return DDS_R8G8B8;
+ }
+ }
+ }
+ else if( header.pf.flags & DDPF_FOURCC ) {
+ switch( header.pf.fourcc ) {
+ case FOURCC_DXT1:
+ return DDS_DXT1;
+ case FOURCC_DXT2:
+ return DDS_DXT2;
+ case FOURCC_DXT3:
+ return DDS_DXT3;
+ case FOURCC_DXT4:
+ return DDS_DXT4;
+ case FOURCC_DXT5:
+ return DDS_DXT5;
+ case FOURCC_RXGB:
+ return DDS_RXGB;
+ case FOURCC_ATI2:
+ return DDS_ATI2;
+ }
+ }
+ return DDS_UNKNOWN;
+ }
+
+ static bool IsCubeMap( const DDSHeader & header )
+ {
+ return header.caps.caps2 & DDSCAPS2_CUBEMAP;
+ }
+
+ static bool IsSupported( const DDSHeader & header )
+ {
+ if( header.caps.caps2 & DDSCAPS2_VOLUME ) {
+ return false;
+ }
+ if( GetType(header) == DDS_UNKNOWN ) {
+ return false;
+ }
+ return true;
+ }
+
+ static bool LoadA8R8G8B8( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ for( uint y = 0; y < h; y++ ) {
+ RGBA *scanline = img[y];
+ for( uint x = 0; x < w; x++ ) {
+ uchar r, g, b, a;
+
+ s.readK(&b, sizeof(b));
+ s.readK(&g, sizeof(g));
+ s.readK(&r, sizeof(r));
+ s.readK(&a, sizeof(a));
+
+ scanline[x] = RGBA(r, g, b, a);
+ }
+ }
+
+ return true;
+ }
+
+ static bool LoadR8G8B8( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ for( uint y = 0; y < h; y++ ) {
+ RGBA * scanline = img[y];
+ for( uint x = 0; x < w; x++ )
+ {
+ uchar r, g, b;
+
+ s.readK(&b, sizeof(b));
+ s.readK(&g, sizeof(g));
+ s.readK(&r, sizeof(r));
+
+ scanline[x] = RGBA(r, g, b, 255);
+ }
+ }
+
+ return true;
+ }
+
+ static bool LoadA1R5G5B5( ifstreamK & s, const DDSHeader & header, RGBA **img )
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ for( uint y = 0; y < h; y++ ) {
+ RGBA * scanline = img[y];
+ for( uint x = 0; x < w; x++ ) {
+ Color1555 color;
+ s.readK(&color.u, sizeof(color.u));
+ uchar a = (color.c.a != 0) ? 0xFF : 0;
+ uchar r = (color.c.r << 3) | (color.c.r >> 2);
+ uchar g = (color.c.g << 3) | (color.c.g >> 2);
+ uchar b = (color.c.b << 3) | (color.c.b >> 2);
+ scanline[x] = RGBA(r, g, b, a);
+ }
+ }
+
+ return true;
+ }
+
+ static bool LoadA4R4G4B4( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ for( uint y = 0; y < h; y++ ) {
+ RGBA * scanline = img[y];
+ for( uint x = 0; x < w; x++ ) {
+ Color4444 color;
+ s.readK(&color.u, sizeof(color.u));
+ uchar a = (color.c.a << 4) | color.c.a;
+ uchar r = (color.c.r << 4) | color.c.r;
+ uchar g = (color.c.g << 4) | color.c.g;
+ uchar b = (color.c.b << 4) | color.c.b;
+ scanline[x] = RGBA(r, g, b, a);
+ }
+ }
+
+ return true;
+ }
+
+ static bool LoadR5G6B5( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ for( uint y = 0; y < h; y++ ) {
+ RGBA * scanline = img[y];
+ for( uint x = 0; x < w; x++ ) {
+ Color565 color;
+ s.readK(&color.u, sizeof(color.u));
+ uchar r = (color.c.r << 3) | (color.c.r >> 2);
+ uchar g = (color.c.g << 2) | (color.c.g >> 4);
+ uchar b = (color.c.b << 3) | (color.c.b >> 2);
+ scanline[x] = RGBA(r, g, b, 255);
+ }
+ }
+
+ return true;
+ }
+
+ static ifstreamK & operator>> ( ifstreamK & s, Color565 & c )
+ {
+ s.readK(&c.u, sizeof(c.u));
+
+ return s;
+ }
+
+ struct BlockDXT
+ {
+ Color565 col0;
+ Color565 col1;
+ uchar row[4];
+
+ void GetColors( Color8888 color_array[4] )
+ {
+ color_array[0].r = (col0.c.r << 3) | (col0.c.r >> 2);
+ color_array[0].g = (col0.c.g << 2) | (col0.c.g >> 4);
+ color_array[0].b = (col0.c.b << 3) | (col0.c.b >> 2);
+ color_array[0].a = 0xFF;
+
+ color_array[1].r = (col1.c.r << 3) | (col1.c.r >> 2);
+ color_array[1].g = (col1.c.g << 2) | (col1.c.g >> 4);
+ color_array[1].b = (col1.c.b << 3) | (col1.c.b >> 2);
+ color_array[1].a = 0xFF;
+
+ if( col0.u > col1.u ) {
+ // Four-color block: derive the other two colors.
+ color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
+ }
+ else {
+ // Three-color block: derive the other color.
+ color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
+ color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
+ color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
+ color_array[2].a = 0xFF;
+
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+ }
+ }
+ };
+
+ static ifstreamK & operator>> ( ifstreamK & s, BlockDXT & c )
+ {
+ s >> c.col0 >> c.col1;
+
+ s.readK(&c.row[0], sizeof(uchar));
+ s.readK(&c.row[1], sizeof(uchar));
+ s.readK(&c.row[2], sizeof(uchar));
+ s.readK(&c.row[3], sizeof(uchar));
+
+ return s;
+ }
+
+ struct BlockDXTAlphaExplicit {
+ ushort row[4];
+ };
+
+ static ifstreamK & operator>> ( ifstreamK & s, BlockDXTAlphaExplicit & c )
+ {
+ s.readK(&c.row[0], sizeof(ushort));
+ s.readK(&c.row[1], sizeof(ushort));
+ s.readK(&c.row[2], sizeof(ushort));
+ s.readK(&c.row[3], sizeof(ushort));
+
+ return s;
+ }
+
+ struct BlockDXTAlphaLinear {
+ uchar alpha0;
+ uchar alpha1;
+ uchar bits[6];
+
+ void GetAlphas( uchar alpha_array[8] )
+ {
+ alpha_array[0] = alpha0;
+ alpha_array[1] = alpha1;
+
+ // 8-alpha or 6-alpha block?
+ if( alpha_array[0] > alpha_array[1] )
+ {
+ // 8-alpha block: derive the other 6 alphas.
+ // 000 = alpha_0, 001 = alpha_1, others are interpolated
+
+ alpha_array[2] = ( 6 * alpha0 + alpha1) / 7; // bit code 010
+ alpha_array[3] = ( 5 * alpha0 + 2 * alpha1) / 7; // Bit code 011
+ alpha_array[4] = ( 4 * alpha0 + 3 * alpha1) / 7; // Bit code 100
+ alpha_array[5] = ( 3 * alpha0 + 4 * alpha1) / 7; // Bit code 101
+ alpha_array[6] = ( 2 * alpha0 + 5 * alpha1) / 7; // Bit code 110
+ alpha_array[7] = ( alpha0 + 6 * alpha1) / 7; // Bit code 111
+ }
+ else
+ {
+ // 6-alpha block: derive the other alphas.
+ // 000 = alpha_0, 001 = alpha_1, others are interpolated
+
+ alpha_array[2] = (4 * alpha0 + alpha1) / 5; // Bit code 010
+ alpha_array[3] = (3 * alpha0 + 2 * alpha1) / 5; // Bit code 011
+ alpha_array[4] = (2 * alpha0 + 3 * alpha1) / 5; // Bit code 100
+ alpha_array[5] = ( alpha0 + 4 * alpha1) / 5; // Bit code 101
+ alpha_array[6] = 0x00; // Bit code 110
+ alpha_array[7] = 0xFF; // Bit code 111
+ }
+ }
+
+ void GetBits( uchar bit_array[16] )
+ {
+ uint b = (uint &) bits[0];
+ bit_array[0] = uchar(b & 0x07); b >>= 3;
+ bit_array[1] = uchar(b & 0x07); b >>= 3;
+ bit_array[2] = uchar(b & 0x07); b >>= 3;
+ bit_array[3] = uchar(b & 0x07); b >>= 3;
+ bit_array[4] = uchar(b & 0x07); b >>= 3;
+ bit_array[5] = uchar(b & 0x07); b >>= 3;
+ bit_array[6] = uchar(b & 0x07); b >>= 3;
+ bit_array[7] = uchar(b & 0x07); b >>= 3;
+
+ b = (uint &) bits[3];
+ bit_array[8] = uchar(b & 0x07); b >>= 3;
+ bit_array[9] = uchar(b & 0x07); b >>= 3;
+ bit_array[10] = uchar(b & 0x07); b >>= 3;
+ bit_array[11] = uchar(b & 0x07); b >>= 3;
+ bit_array[12] = uchar(b & 0x07); b >>= 3;
+ bit_array[13] = uchar(b & 0x07); b >>= 3;
+ bit_array[14] = uchar(b & 0x07); b >>= 3;
+ bit_array[15] = uchar(b & 0x07); b >>= 3;
+ }
+ };
+
+ static ifstreamK & operator>> ( ifstreamK & s, BlockDXTAlphaLinear & c )
+ {
+ s.readK(&c.alpha0, sizeof(c.alpha0));
+ s.readK(&c.alpha1, sizeof(c.alpha1));
+
+ s.readK(&c.bits[0], sizeof(uchar));
+ s.readK(&c.bits[1], sizeof(uchar));
+ s.readK(&c.bits[2], sizeof(uchar));
+ s.readK(&c.bits[3], sizeof(uchar));
+ s.readK(&c.bits[4], sizeof(uchar));
+ s.readK(&c.bits[5], sizeof(uchar));
+
+ return s;
+ }
+
+ static bool LoadDXT1( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ BlockDXT block;
+ RGBA * scanline[4];
+
+ for( uint y = 0; y < h; y += 4 ) {
+ for( uint j = 0; j < 4; j++ ) {
+ scanline[j] = img[y + j];
+ }
+
+ for( uint x = 0; x < w; x += 4 ) {
+
+ // Read 64bit color block.
+ s >> block;
+
+ // Decode color block.
+ Color8888 color_array[4];
+ block.GetColors(color_array);
+
+ // bit masks = 00000011, 00001100, 00110000, 11000000
+ const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 };
+ const int shift[4] = { 0, 2, 4, 6 };
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ /*if( img.valid( x+i, y+j ) ) */{
+
+ uint idx = (block.row[j] & masks[i]) >> shift[i];
+ scanline[j][x+i] = RGBA(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a);
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static bool LoadDXT3( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ BlockDXT block;
+ BlockDXTAlphaExplicit alpha;
+ RGBA * scanline[4];
+
+ for( uint y = 0; y < h; y += 4 ) {
+ for( uint j = 0; j < 4; j++ ) {
+ scanline[j] = img[y + j];
+ }
+ for( uint x = 0; x < w; x += 4 ) {
+
+ // Read 128bit color block.
+ s >> alpha;
+ s >> block;
+
+ // Decode color block.
+ Color8888 color_array[4];
+ block.GetColors(color_array);
+
+ // bit masks = 00000011, 00001100, 00110000, 11000000
+ const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 };
+ const int shift[4] = { 0, 2, 4, 6 };
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ ushort a = alpha.row[j];
+ for( uint i = 0; i < 4; i++ ) {
+ /*if( img.valid( x+i, y+j ) ) */{
+ uint idx = (block.row[j] & masks[i]) >> shift[i];
+ color_array[idx].a = a & 0x0f;
+ color_array[idx].a = color_array[idx].a | (color_array[idx].a << 4);
+ scanline[j][x+i] = RGBA(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a);
+ }
+ a >>= 4;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ static bool LoadDXT2( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ if( !LoadDXT3(s, header, img) ) return false;
+ //UndoPremultiplyAlpha(img);
+ return true;
+ }
+
+ static bool LoadDXT5( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ BlockDXT block;
+ BlockDXTAlphaLinear alpha;
+ RGBA * scanline[4];
+
+ for( uint y = 0; y < h; y += 4 ) {
+ for( uint j = 0; j < 4; j++ ) {
+ scanline[j] = img[y + j];
+ }
+ for( uint x = 0; x < w; x += 4 ) {
+
+ // Read 128bit color block.
+ s >> alpha;
+ s >> block;
+
+ // Decode color block.
+ Color8888 color_array[4];
+ block.GetColors(color_array);
+
+ uchar alpha_array[8];
+ alpha.GetAlphas(alpha_array);
+
+ uchar bit_array[16];
+ alpha.GetBits(bit_array);
+
+ // bit masks = 00000011, 00001100, 00110000, 11000000
+ const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 };
+ const int shift[4] = { 0, 2, 4, 6 };
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ /*if( img.valid( x+i, y+j ) ) */{
+ uint idx = (block.row[j] & masks[i]) >> shift[i];
+ color_array[idx].a = alpha_array[bit_array[j*4+i]];
+ scanline[j][x+i] = RGBA(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a);
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+ static bool LoadDXT4( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ if( !LoadDXT5(s, header, img) ) return false;
+ //UndoPremultiplyAlpha(img);
+ return true;
+ }
+
+ static bool LoadRXGB( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ BlockDXT block;
+ BlockDXTAlphaLinear alpha;
+ RGBA * scanline[4];
+
+ for( uint y = 0; y < h; y += 4 ) {
+ for( uint j = 0; j < 4; j++ ) {
+ scanline[j] = img[y + j];
+ }
+ for( uint x = 0; x < w; x += 4 ) {
+
+ // Read 128bit color block.
+ s >> alpha;
+ s >> block;
+
+ // Decode color block.
+ Color8888 color_array[4];
+ block.GetColors(color_array);
+
+ uchar alpha_array[8];
+ alpha.GetAlphas(alpha_array);
+
+ uchar bit_array[16];
+ alpha.GetBits(bit_array);
+
+ // bit masks = 00000011, 00001100, 00110000, 11000000
+ const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 };
+ const int shift[4] = { 0, 2, 4, 6 };
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ /*if( img.valid( x+i, y+j ) ) */{
+ uint idx = (block.row[j] & masks[i]) >> shift[i];
+ color_array[idx].a = alpha_array[bit_array[j*4+i]];
+ scanline[j][x+i] = RGBA(color_array[idx].a, color_array[idx].g, color_array[idx].b, 255);
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static bool LoadATI2( ifstreamK & s, const DDSHeader & header, RGBA **img)
+ {
+ const uint w = header.width;
+ const uint h = header.height;
+
+ BlockDXTAlphaLinear xblock;
+ BlockDXTAlphaLinear yblock;
+ RGBA * scanline[4];
+
+ for( uint y = 0; y < h; y += 4 ) {
+ for( uint j = 0; j < 4; j++ ) {
+ scanline[j] = img[y + j];
+ }
+ for( uint x = 0; x < w; x += 4 ) {
+
+ // Read 128bit color block.
+ s >> xblock;
+ s >> yblock;
+
+ // Decode color block.
+ uchar xblock_array[8];
+ xblock.GetAlphas(xblock_array);
+
+ uchar xbit_array[16];
+ xblock.GetBits(xbit_array);
+
+ uchar yblock_array[8];
+ yblock.GetAlphas(yblock_array);
+
+ uchar ybit_array[16];
+ yblock.GetBits(ybit_array);
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ /*if( img.valid( x+i, y+j ) ) */{
+ const uchar nx = xblock_array[xbit_array[j*4+i]];
+ const uchar ny = yblock_array[ybit_array[j*4+i]];
+
+ const float fx = float(nx) / 127.5f - 1.0f;
+ const float fy = float(ny) / 127.5f - 1.0f;
+ const float fz = sqrtf(1.0f - fx*fx - fy*fy);
+ const uchar nz = uchar((fz + 1.0f) * 127.5f);
+
+ scanline[j][x+i] = RGBA(nx, ny, nz, 255);
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ typedef bool (* TextureLoader)( ifstreamK & s, const DDSHeader & header, RGBA **);
+
+ // Get an appropiate texture loader for the given type.
+ static TextureLoader GetTextureLoader( DDSType type ) {
+ switch( type ) {
+ case DDS_A8R8G8B8:
+ return LoadA8R8G8B8;
+ case DDS_A1R5G5B5:
+ return LoadA1R5G5B5;
+ case DDS_A4R4G4B4:
+ return LoadA4R4G4B4;
+ case DDS_R8G8B8:
+ return LoadR8G8B8;
+ case DDS_R5G6B5:
+ return LoadR5G6B5;
+ case DDS_DXT1:
+ return LoadDXT1;
+ case DDS_DXT2:
+ return LoadDXT2;
+ case DDS_DXT3:
+ return LoadDXT3;
+ case DDS_DXT4:
+ return LoadDXT4;
+ case DDS_DXT5:
+ return LoadDXT5;
+ case DDS_RXGB:
+ return LoadRXGB;
+ case DDS_ATI2:
+ return LoadATI2;
+ default:
+ return NULL;
+ };
+ }
+
+
+ // Load a 2d texture.
+ static bool LoadTexture( ifstreamK & s, const DDSHeader & header, RGBA ***img)
+ {
+ if(!MALLOC_ROWS(img, header.width * sizeof(RGBA), header.height))
+ return false;
+
+ // Read image.
+ DDSType type = GetType( header );
+
+ TextureLoader loader = GetTextureLoader( type );
+ if( loader == NULL ) {
+ return false;
+ }
+
+ return loader( s, header, *img );
+ }
+
+
+ static int FaceOffset( const DDSHeader & header ) {
+
+ DDSType type = GetType( header );
+
+ int mipmap = max(header.mipmapcount, 1);
+ int size = 0;
+ int w = header.width;
+ int h = header.height;
+
+ if( type >= DDS_DXT1 ) {
+ int multiplier = (type == DDS_DXT1) ? 8 : 16;
+ do {
+ int face_size = max(w/4,1) * max(h/4,1) * multiplier;
+ size += face_size;
+ w >>= 1;
+ h >>= 1;
+ } while( --mipmap );
+ }
+ else {
+ int multiplier = header.pf.bitcount / 8;
+ do {
+ int face_size = w * h * multiplier;
+ size += face_size;
+ w = max( w>>1, 1 );
+ h = max( h>>1, 1 );
+ } while( --mipmap );
+ }
+
+ return size;
+ }
+
+#if CUBE_LAYOUT == HORIZONTAL
+ static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {3, 1} };
+#elif CUBE_LAYOUT == VERTICAL
+ static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {1, 3} };
+#endif
+ static int face_flags[6] = {
+ DDSCAPS2_CUBEMAP_POSITIVEX,
+ DDSCAPS2_CUBEMAP_NEGATIVEX,
+ DDSCAPS2_CUBEMAP_POSITIVEY,
+ DDSCAPS2_CUBEMAP_NEGATIVEY,
+ DDSCAPS2_CUBEMAP_POSITIVEZ,
+ DDSCAPS2_CUBEMAP_NEGATIVEZ
+ };
+
+ // Load unwrapped cube map.
+ static bool LoadCubeMap( ifstreamK & s, const DDSHeader & header, RGBA ***img)
+ {
+ int dimw = 0, dimh = 0;
+#if CUBE_LAYOUT == HORIZONTAL
+ dimw = 4 * header.width;
+ dimh = 3 * header.height;
+#elif CUBE_LAYOUT == VERTICAL
+ dimw = 3 * header.width;
+ dimh = 4 * header.height;
+#endif
+
+ if(!MALLOC_ROWS(img, dimw * sizeof(RGBA), dimh))
+ return false;
+
+ // Create dst image.
+
+ DDSType type = GetType( header );
+
+ // Select texture loader.
+ TextureLoader loader = GetTextureLoader( type );
+ if( loader == NULL ) {
+ return false;
+ }
+
+ RGBA **face;
+ if(!MALLOC_ROWS(&face, header.width * sizeof(RGBA), header.height))
+ return false;
+
+ // Create face image.
+ int offset = s.tellg();
+ int size = FaceOffset( header );
+
+ for( int i = 0; i < 6; i++ ) {
+
+ if( !(header.caps.caps2 & face_flags[i]) ) {
+ // Skip face.
+ continue;
+ }
+
+ // Seek device.
+ s.seekg(offset);
+ offset += size;
+
+ // Load face from stream.
+ if( !loader( s, header, face ) ) {
+ return false;
+ }
+
+#if CUBE_LAYOUT == VERTICAL
+ if( i == 5 ) {
+// face = face.mirror(true, true);
+ }
+#endif
+
+ // Compute face offsets.
+ int offset_x = face_offset[i][0] * header.width;
+ int offset_y = face_offset[i][1] * header.height;
+
+ // Copy face on the image.
+ for( uint y = 0; y < header.height; y++ )
+ {
+ RGBA * src = face[y];
+ RGBA * dst = (*img)[y + offset_y] + offset_x;
+ memcpy( dst, src, sizeof(RGBA) * header.width );
+ }
+ }
+
+ return true;
+ }
+
+}
+
+bool dds_read(const std::string &file, DDSINFO &dds)
+{
+ ifstreamK s;
+ s.open(file.c_str(), std::ios::binary | std::ios::in);
+
+ if(!s.good())
+ return false;
+
+ // Validate header.
+ uint fourcc;
+ s.readK(&fourcc, sizeof(uint));
+
+ if(fourcc != FOURCC_DDS)
+ return false;
+
+ // Read image header.
+ DDSHeader header;
+ s >> header;
+
+ // Check image file format.
+ if(!s.good() || !IsValid(header) || !IsSupported(header))
+ return false;
+
+ RGBA **img = 0;
+ bool result;
+
+ if(IsCubeMap(header))
+ result = LoadCubeMap(s, header, &img);
+ else
+ result = LoadTexture(s, header, &img);
+
+ if(result)
+ {
+ dds.w = header.width;
+ dds.h = header.height;
+ dds.img = img;
+ }
+
+ return result;
+}
diff --git a/kernel/kls_dds/dds.h b/kernel/kls_dds/dds.h
new file mode 100644
index 0000000..5e7af28
--- /dev/null
+++ b/kernel/kls_dds/dds.h
@@ -0,0 +1,36 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2007 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef DDS_H
+#define DDS_H
+
+struct RGBA;
+struct DDSINFO;
+
+struct DDSINFO
+{
+ int w, h;
+ RGBA **img;
+};
+
+bool dds_read(const std::string &file, DDSINFO&);
+
+#endif
diff --git a/kernel/kls_dds/fmt_codec_dds.cpp b/kernel/kls_dds/fmt_codec_dds.cpp
new file mode 100644
index 0000000..305c207
--- /dev/null
+++ b/kernel/kls_dds/fmt_codec_dds.cpp
@@ -0,0 +1,143 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2007 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_dds_defs.h"
+#include "fmt_codec_dds.h"
+
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "../xpm/codec_dds.xpm"
+
+typedef RGBA* RGBAP;
+
+inline void FREE_ROWS(RGBAP **A, const int H)
+{
+ if(*A)
+ {
+ for(s32 i = 0;i < H;i++)
+ {
+ if((*A)[i])
+ free((*A)[i]);
+ }
+
+ free(*A);
+ *A = 0;
+ }
+}
+
+/*
+ *
+ * DDS
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "DirectDraw Surface";
+ o->filter = "*.dds ";
+ o->mime = "";
+ o->mimetype = "image/x-dds";
+ o->config = "";
+ o->pixmap = codec_dds;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ dds.img = 0;
+ dds.w = dds.h = 0;
+
+ if(!dds_read(file, dds))
+ return SQE_R_BADFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ image.w = dds.w;
+ image.h = dds.h;
+ image.bpp = 32;
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(32);
+
+ finfo.image.push_back(image);
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+
+ memcpy(scan, dds.img[line], dds.w * sizeof(RGBA));
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ FREE_ROWS(&dds.img, dds.h);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_dds/fmt_codec_dds_defs.h b/kernel/kls_dds/fmt_codec_dds_defs.h
new file mode 100644
index 0000000..182687c
--- /dev/null
+++ b/kernel/kls_dds/fmt_codec_dds_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2007 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_dds
+#define KSQUIRREL_CODEC_DEFS_dds
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_dicom/Makefile.am b/kernel/kls_dicom/Makefile.am
new file mode 100644
index 0000000..81d024c
--- /dev/null
+++ b/kernel/kls_dicom/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include -I../kls_png
+
+bin_SCRIPTS = ksquirrel-libs-dicom2png
+
+pkglib_LTLIBRARIES = libkls_dicom.la
+
+libkls_dicom_la_SOURCES = fmt_codec_png.cpp fmt_codec_png_defs.h
+
+libkls_dicom_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_dicom_la_LIBADD = ${SQ_LOCAL_RPATH} -L../kls_png/ksquirrel-libs-png -lksquirrel-libs-png
+
+AM_CXXFLAGS = -DCODEC_DICOM -DDICOM=\"${bindir}/ksquirrel-libs-dicom2png\"
+
+EXTRA_DIST = ksquirrel-libs-dicom2png.in
diff --git a/kernel/kls_dicom/fmt_codec_png.cpp b/kernel/kls_dicom/fmt_codec_png.cpp
new file mode 100644
index 0000000..66c43ee
--- /dev/null
+++ b/kernel/kls_dicom/fmt_codec_png.cpp
@@ -0,0 +1,655 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs-png/png.h"
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_png_defs.h"
+#include "fmt_codec_png.h"
+
+#if defined CODEC_SVG || defined CODEC_DICOM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_SVG
+#include "../xpm/codec_svg.xpm"
+#elif defined CODEC_DICOM
+#include "../xpm/codec_dicom.xpm"
+#else
+#include "../xpm/codec_png.xpm"
+#endif
+
+/*
+ *
+ * PNG (pronounced "ping") is a bitmap file format used to transmit and
+ * store bitmapped images. PNG supports the capability of storing up to
+ * 16 bits (gray-scale) or 48 bits (truecolor) per pixel, and up to 16 bits
+ * of alpha data. It handles the progressive display
+ * of image data and the storage of gamma,
+ * transparency and textual information, and it uses an efficient and
+ * lossless form of data compression.
+ *
+ */
+
+inline bool MALLOC_ROWS(png_bytep **A, const int RB, const int H)
+{
+ *A = (png_bytep*)malloc(H * sizeof(png_bytep*));
+
+ if(!*A)
+ return false;
+
+ for(s32 row = 0; row < H; row++)
+ (*A)[row] = 0;
+
+ for(s32 row = 0; row < (s32)H; row++)
+ {
+ (*A)[row] = (png_bytep)malloc(RB);
+
+ if(!(*A)[row])
+ return false;
+
+ memset((*A)[row], 0, RB);
+ }
+
+ return true;
+}
+
+inline void FREE_ROWS(png_bytep **A, const int H)
+{
+ if(*A)
+ {
+ for(s32 i = 0;i < H;i++)
+ {
+ if((*A)[i])
+ free((*A)[i]);
+ }
+
+ free(*A);
+ *A = 0;
+ }
+}
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+#ifdef CODEC_SVG
+ o->version = "0.1.2";
+ o->name = "Scalable Vector Graphics";
+ o->filter = "*.svg *.svgz ";
+ o->config = std::string(SVG_UI); // SVG_UI comes from Makefile.am
+ o->mime = "";
+ o->mimetype = "image/svg+xml";
+ o->pixmap = codec_svg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DICOM
+ o->version = "1.1.3";
+ o->name = "DICOM";
+ o->filter = "*.dcm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-dicom";
+ o->pixmap = codec_dicom;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "1.1.3";
+ o->name = "Portable Network Graphics";
+ o->filter = "*.png ";
+ o->config = "";
+ o->mime = "\x0089\x0050\x004E\x0047\x000D\x000A\x001A\x000A";
+ o->mimetype = "image/png";
+ o->pixmap = codec_png;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#ifdef CODEC_ANOTHER
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_int;
+ val.iVal = 1;
+
+ m_settings["scale"] = val;
+}
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ png_ptr = 0;
+ info_ptr = 0;
+ fptr = 0;
+ frame = 0;
+ prev = 0;
+ cur = 0;
+ zerror = false;
+
+#ifdef CODEC_SVG
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("scale");
+
+ // percents / 100
+ int scale = (it == m_settings.end() || (*it).second.type != settings_value::v_int)
+ ? 1 : (*it).second.iVal;
+
+ if(scale < 1 || scale > 10)
+ scale = 1;
+
+ char z[32];
+ snprintf(z, 32, "%d", scale);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(SVG2PNG, SVG2PNG, "--binary", RSVG, "--input", file.c_str(), "--output", tmp.c_str(), "-z", z, (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DICOM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DICOM, DICOM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+ fptr = fopen(file.c_str(), "rb");
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ if((png_ptr = my_png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)) == NULL)
+ {
+ zerror = true;
+ return SQE_R_NOMEMORY;
+ }
+
+ if((info_ptr = my_png_create_info_struct(png_ptr)) == NULL)
+ {
+ zerror = true;
+ return SQE_R_NOMEMORY;
+ }
+
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ my_png_init_io(png_ptr, fptr);
+ my_png_read_info(png_ptr, info_ptr);
+ my_png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, (int*)0, (int*)0);
+
+ img.w = next_frame_width = width;
+ img.h = next_frame_height = height;
+ img.bpp = bit_depth;
+
+ if(img.bpp == 16)
+ my_png_set_strip_16(png_ptr);
+
+ if(img.bpp < 8)
+ my_png_set_packing(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_GRAY && img.bpp < 8)
+ my_png_set_gray_1_2_4_to_8(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_PALETTE)
+ my_png_set_palette_to_rgb(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ my_png_set_gray_to_rgb(png_ptr);
+
+ if(my_png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ my_png_set_tRNS_to_alpha(png_ptr);
+
+ my_png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+ number_passes = my_png_set_interlace_handling(png_ptr);
+
+ my_png_read_update_info(png_ptr, info_ptr);
+
+ finfo.animated = !!my_png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL);
+
+ frames = finfo.animated ? my_png_get_num_frames(png_ptr, info_ptr) : 1;
+
+ if(!frames) return SQE_R_BADFILE;
+
+ img.interlaced = number_passes > 1;
+ img.passes = finfo.animated ? 1 : number_passes;
+
+ if(finfo.animated)
+ {
+ if(!MALLOC_ROWS(&prev, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+
+ if(!MALLOC_ROWS(&cur, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+ }
+
+ std::string color_;
+
+ img.hasalpha = (color_type & PNG_COLOR_MASK_ALPHA);
+
+ switch((color_type & ~PNG_COLOR_MASK_ALPHA))
+ {
+ case PNG_COLOR_TYPE_RGB: color_ = "RGB"; break;
+ case PNG_COLOR_TYPE_PALETTE: color_ = "Color indexed"; break;
+ case PNG_COLOR_TYPE_GRAY: color_ = "Grayscale"; break;
+
+ default:
+ color_ = "Unknown";
+ }
+
+ if(img.hasalpha)
+ color_ += " with ALPHA";
+
+ img.compression = "Deflate method 8, 32K window";
+ img.colorspace = color_;
+ if(!finfo.animated) img.delay = 0;
+
+#ifdef PNG_TEXT_SUPPORTED
+ png_textp lines = info_ptr->text;
+
+ if(!lines || !info_ptr->num_text)
+ return SQE_OK;
+
+ for(s32 i = 0;i < info_ptr->num_text;i++)
+ {
+ fmt_metaentry mt;
+
+ mt.group = lines[i].key;
+ mt.data = lines[i].text;
+
+ addmeta(mt);
+ }
+#endif
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == frames)
+ return SQE_NOTOK;
+
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ if(finfo.animated)
+ {
+ if(currentImage)
+ {
+ if(next_frame_dispose_op == PNG_DISPOSE_OP_BACKGROUND)
+ {
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ memset(cur[j]+next_frame_x_offset*sizeof(RGBA), 0, next_frame_width * sizeof(RGBA));
+ }
+ else if(next_frame_dispose_op == PNG_DISPOSE_OP_PREVIOUS)
+ {
+ for(u32 i = 0;i < height;i++)
+ memcpy(cur[i], prev[i], width*sizeof(RGBA));
+ }
+ else // next_frame_dispose_op == PNG_DISPOSE_OP_NONE
+ {
+ }
+
+ for(u32 i = 0;i < height;i++)
+ memcpy(prev[i], cur[i], width*sizeof(RGBA));
+ }
+ else if(my_png_get_first_frame_is_hidden(png_ptr, info_ptr))
+ {
+ if(!MALLOC_ROWS(&frame, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+
+ my_png_read_frame_head(png_ptr, info_ptr);
+ my_png_read_image(png_ptr, frame);
+
+ FREE_ROWS(&frame, height);
+
+ frames--;
+
+ if(frames == 1)
+ {
+ my_png_read_frame_head(png_ptr, info_ptr);
+ finfo.animated = false;
+ img.passes = number_passes;
+ finfo.image.push_back(img);
+ return SQE_OK;
+ }
+ else if(!frames)
+ return SQE_R_BADFILE; // oops?
+ }
+
+ FREE_ROWS(&frame, next_frame_height);
+
+ my_png_read_frame_head(png_ptr, info_ptr);
+
+ if(my_png_get_valid(png_ptr, info_ptr, PNG_INFO_fcTL))
+ {
+ my_png_get_next_frame_fcTL(png_ptr, info_ptr,
+ &next_frame_width, &next_frame_height,
+ &next_frame_x_offset, &next_frame_y_offset,
+ &next_frame_delay_num, &next_frame_delay_den,
+ &next_frame_dispose_op, &next_frame_blend_op);
+ }
+ else
+ {
+ next_frame_width = width;
+ next_frame_height = height;
+ next_frame_x_offset = 0;
+ next_frame_y_offset = 0;
+ next_frame_dispose_op = PNG_DISPOSE_OP_BACKGROUND;
+ next_frame_blend_op = PNG_BLEND_OP_SOURCE;
+ }
+
+ if(!next_frame_delay_den) next_frame_delay_den = 100;
+
+ img.delay = (s32)(((double)next_frame_delay_num / next_frame_delay_den) * 1000);
+
+ if(next_frame_width + next_frame_x_offset > width || next_frame_height + next_frame_y_offset > height)
+ return SQE_R_BADFILE;
+
+ if(!MALLOC_ROWS(&frame, next_frame_width * sizeof(RGBA), next_frame_height))
+ return SQE_R_NOMEMORY;
+
+ my_png_read_image(png_ptr, frame);
+
+ // copy all pixel values including alpha
+ if(!currentImage || next_frame_blend_op == PNG_BLEND_OP_SOURCE)
+ {
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ memcpy(cur[j]+next_frame_x_offset*sizeof(RGBA), frame[i], next_frame_width * sizeof(RGBA));
+ }
+ else // over
+ {
+ RGBA *src, *dst;
+
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ {
+ src = (RGBA *)frame[i];
+ dst = (RGBA *)(cur[j]+next_frame_x_offset*sizeof(RGBA));
+ u32 k = next_frame_width;
+
+ while(k--)
+ {
+ // fully transparent foreground
+ if(src->a == 0)
+ ;
+ else if(src->a == 255 || dst->a == 0)
+ *dst = *src;
+ else // composite
+ {
+ dst->r = ((src->a * (src->r - dst->r))>>8) + dst->r;
+ dst->g = ((src->a * (src->g - dst->g))>>8) + dst->g;
+ dst->b = ((src->a * (src->b - dst->b))>>8) + dst->b;
+ //dst->a = ((src->a * (src->a - dst->a))>>8) + dst->a;
+ }
+
+ src++;
+ dst++;
+ }
+ }
+ }
+ }
+
+ finfo.image.push_back(img);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+
+ line++;
+
+ if(zerror || setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ if(finfo.animated)
+ memcpy(scan, cur[line], im->w * sizeof(RGBA));
+ else
+ my_png_read_row(png_ptr, (png_bytep)scan, png_bytep_NULL);
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(png_ptr) my_png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+
+ if(fptr) fclose(fptr);
+
+ FREE_ROWS(&frame, next_frame_height);
+ FREE_ROWS(&prev, height);
+ FREE_ROWS(&cur, height);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#ifdef CODEC_PNG
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = true;
+ opt->compression_scheme = CompressionInternal;
+ opt->compression_min = 1;
+ opt->compression_max = 9;
+ opt->compression_def = 7;
+ opt->passes = 8;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ m_png_ptr = 0;
+ m_info_ptr = 0;
+ m_fptr = 0;
+ m_zerror = false;
+
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ m_fptr = fopen(file.c_str(), "wb");
+
+ if(!m_fptr)
+ return SQE_W_NOFILE;
+
+ m_png_ptr = my_png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+
+ if(!m_png_ptr)
+ {
+ m_zerror = true;
+ return SQE_W_NOMEMORY;
+ }
+
+ m_info_ptr = my_png_create_info_struct(m_png_ptr);
+
+ if(!m_info_ptr)
+ {
+ m_zerror = true;
+ return SQE_W_NOMEMORY;
+ }
+
+ if(setjmp(png_jmpbuf(m_png_ptr)))
+ {
+ m_zerror = true;
+ return SQE_W_ERROR;
+ }
+
+ my_png_init_io(m_png_ptr, m_fptr);
+
+ my_png_set_IHDR(m_png_ptr, m_info_ptr, writeimage.w, writeimage.h, 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ ((writeopt.interlaced) ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE),
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_color_8 sig_bit;
+
+ sig_bit.red = 8;
+ sig_bit.green = 8;
+ sig_bit.blue = 8;
+ sig_bit.alpha = 8;
+
+ my_png_set_sBIT(m_png_ptr, m_info_ptr, &sig_bit);
+
+ s32 factor = (writeopt.compression_level < 1 || writeopt.compression_level > 9) ? 1 : writeopt.compression_level;
+
+ my_png_set_compression_level(m_png_ptr, factor);
+
+ my_png_write_info(m_png_ptr, m_info_ptr);
+
+ my_png_set_shift(m_png_ptr, &sig_bit);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ my_png_set_swap(m_png_ptr);
+
+ my_png_set_packswap(m_png_ptr);
+
+ my_png_set_interlace_handling(m_png_ptr);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ if(m_zerror || setjmp(png_jmpbuf(m_png_ptr)))
+ {
+ m_zerror = true;
+ return SQE_W_ERROR;
+ }
+
+ m_row_pointer = (png_bytep)scan;
+
+ my_png_write_rows(m_png_ptr, &m_row_pointer, 1);
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ if(m_png_ptr && !m_zerror) my_png_write_end(m_png_ptr, m_info_ptr);
+ if(m_png_ptr) my_png_destroy_write_struct(&m_png_ptr, &m_info_ptr);
+ if(m_fptr) fclose(m_fptr);
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("png");
+}
+
+#endif
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_dicom/fmt_codec_png_defs.h b/kernel/kls_dicom/fmt_codec_png_defs.h
new file mode 100644
index 0000000..afef4ac
--- /dev/null
+++ b/kernel/kls_dicom/fmt_codec_png_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_png
+#define KSQUIRREL_READ_IMAGE_png
+
+// Nothing to define at this moment :)
+
+#endif
diff --git a/kernel/kls_dicom/ksquirrel-libs-dicom2png.in b/kernel/kls_dicom/ksquirrel-libs-dicom2png.in
new file mode 100644
index 0000000..96e0138
--- /dev/null
+++ b/kernel/kls_dicom/ksquirrel-libs-dicom2png.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@MEDCON@ --without-prefix -f "$1" -e 0:0 -c - png > "$2" \ No newline at end of file
diff --git a/kernel/kls_djvu/Makefile.am b/kernel/kls_djvu/Makefile.am
new file mode 100644
index 0000000..e546bff
--- /dev/null
+++ b/kernel/kls_djvu/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_djvu.la
+
+libkls_djvu_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_djvu_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_djvu_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DDJVU_UI=\"${pkgdatadir}/libkls_djvu.so.ui\" -DCODEC_DJVU -DDJVU=\"${DJVU}\" -DCODEC_ANOTHER
+
+EXTRA_DIST = libkls_djvu.so.ui
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 libkls_djvu.so.ui $(DESTDIR)$(pkgdatadir)/libkls_djvu.so.ui
diff --git a/kernel/kls_djvu/fmt_codec_pnm.cpp b/kernel/kls_djvu/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_djvu/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_djvu/fmt_codec_pnm_defs.h b/kernel/kls_djvu/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_djvu/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_djvu/libkls_djvu.so.ui b/kernel/kls_djvu/libkls_djvu.so.ui
new file mode 100644
index 0000000..5469d42
--- /dev/null
+++ b/kernel/kls_djvu/libkls_djvu.so.ui
@@ -0,0 +1,195 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Form1</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>313</width>
+ <height>118</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Page number to decode:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>page</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>40</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>no_spinBox</cstring>
+ </property>
+ <property name="prefix">
+ <string>#</string>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Scale down&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QSlider" row="3" column="0">
+ <property name="name">
+ <cstring>scaledown</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>12</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="1">
+ <property name="name">
+ <cstring>no_spinBox_2</cstring>
+ </property>
+ <property name="suffix">
+ <string>x</string>
+ </property>
+ <property name="specialValueText">
+ <string>no</string>
+ </property>
+ <property name="maxValue">
+ <number>12</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>page</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_spinBox</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_spinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>page</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>scaledown</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_spinBox_2</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_spinBox_2</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>scaledown</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kernel/kls_dxf/Makefile.am b/kernel/kls_dxf/Makefile.am
new file mode 100644
index 0000000..7d3fc63
--- /dev/null
+++ b/kernel/kls_dxf/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_dxf.la
+
+libkls_dxf_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_dxf_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_dxf_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DDXF_UI=\"${pkgdatadir}/libkls_dxf.so.ui\" -DCODEC_DXF -DVEC2WEB=\"${VEC2WEB}\" -DCODEC_ANOTHER
+
+EXTRA_DIST = libkls_dxf.so.ui
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 libkls_dxf.so.ui $(DESTDIR)$(pkgdatadir)/libkls_dxf.so.ui
diff --git a/kernel/kls_dxf/fmt_codec_pnm.cpp b/kernel/kls_dxf/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_dxf/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_dxf/fmt_codec_pnm_defs.h b/kernel/kls_dxf/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_dxf/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_dxf/libkls_dxf.so.ui b/kernel/kls_dxf/libkls_dxf.so.ui
new file mode 100644
index 0000000..96a4c98
--- /dev/null
+++ b/kernel/kls_dxf/libkls_dxf.so.ui
@@ -0,0 +1,192 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Form1</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>313</width>
+ <height>118</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Width&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>width</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>500</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>no_spinBox</cstring>
+ </property>
+ <property name="specialValueText">
+ <string>default</string>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Height&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QSlider" row="3" column="0">
+ <property name="name">
+ <cstring>height</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>500</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="1">
+ <property name="name">
+ <cstring>no_spinBox_2</cstring>
+ </property>
+ <property name="specialValueText">
+ <string>default</string>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>width</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_spinBox</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_spinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>width</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>height</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_spinBox_2</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_spinBox_2</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>height</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kernel/kls_eps/Makefile.am b/kernel/kls_eps/Makefile.am
new file mode 100644
index 0000000..5aa673f
--- /dev/null
+++ b/kernel/kls_eps/Makefile.am
@@ -0,0 +1,11 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_eps.la
+
+libkls_eps_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_eps_la_LDFLAGS = ${SQ_RELEASE} -lm
+
+libkls_eps_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_EPS -DEPS2PPM=\"${EPS2PPM}\"
diff --git a/kernel/kls_eps/fmt_codec_pnm.cpp b/kernel/kls_eps/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_eps/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_eps/fmt_codec_pnm_defs.h b/kernel/kls_eps/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_eps/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_fig/Makefile.am b/kernel/kls_fig/Makefile.am
new file mode 100644
index 0000000..7240c61
--- /dev/null
+++ b/kernel/kls_fig/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-fig2ppm
+
+pkglib_LTLIBRARIES = libkls_fig.la
+
+libkls_fig_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_fig_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_fig_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_FIG -DXFIG_S=\"${bindir}/ksquirrel-libs-fig2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-fig2ppm.in \ No newline at end of file
diff --git a/kernel/kls_fig/fmt_codec_pnm.cpp b/kernel/kls_fig/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_fig/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_fig/fmt_codec_pnm_defs.h b/kernel/kls_fig/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_fig/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_fig/ksquirrel-libs-fig2ppm.in b/kernel/kls_fig/ksquirrel-libs-fig2ppm.in
new file mode 100644
index 0000000..2bbd537
--- /dev/null
+++ b/kernel/kls_fig/ksquirrel-libs-fig2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@XFIG@ -L ppm "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_fli/Makefile.am b/kernel/kls_fli/Makefile.am
new file mode 100644
index 0000000..7570336
--- /dev/null
+++ b/kernel/kls_fli/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_fli.la
+
+libkls_fli_la_SOURCES = fmt_codec_fli.cpp fmt_codec_fli_defs.h
+
+libkls_fli_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_fli_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_fli/fmt_codec_fli.cpp b/kernel/kls_fli/fmt_codec_fli.cpp
new file mode 100644
index 0000000..d186d98
--- /dev/null
+++ b/kernel/kls_fli/fmt_codec_fli.cpp
@@ -0,0 +1,449 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_fli_defs.h"
+#include "fmt_codec_fli.h"
+
+#include "../xpm/codec_fli.xpm"
+
+/*
+ *
+ * The FLI file format (sometimes called Flic)
+ * is one of the most popular
+ * animation formats found in the MS-DOS and Windows environments today. FLI is
+ * used widely in animation programs, computer games, and CAD applications
+ * requiring 3D manipulation of vector drawings. Flic, in common
+ * with most animation formats, does not support either audio or video data, but
+ * instead stores only sequences of still image data.
+ *
+ */
+
+// maximum number of frames in FLI is 1024
+#define MAX_FRAME 1024
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.3.2";
+ o->name = "FLI Animation";
+ o->filter = "*.fli ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "video/x-flic";
+ o->pixmap = codec_fli;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ if(!frs.readK(&flic, sizeof(FLICHEADER)))
+ return SQE_R_BADFILE;
+
+ if(flic.FileId != 0xAF11)// && flic.FileId != 0xAF12)
+ return SQE_R_BADFILE;
+
+ if(flic.Flags != 3)
+ cerr << "libSQ_read_fli: WARNING: Flags != 3" << endl;
+
+ memset(pal, 0, 768);
+
+ currentImage = -1;
+
+ buf = (u8**)calloc(flic.Height, sizeof(u8*));
+
+ if(!buf)
+ return SQE_R_NOMEMORY;
+
+ for(s32 i = 0;i < flic.Height;i++)
+ {
+ buf[i] = (u8*)0;
+ }
+
+ for(s32 i = 0;i < flic.Height;i++)
+ {
+ buf[i] = (u8*)calloc(flic.Width, sizeof(u8));
+
+ if(!buf[i])
+ return SQE_R_NOMEMORY;
+ }
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == flic.NumberOfFrames || currentImage == MAX_FRAME)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ image.w = flic.Width;
+ image.h = flic.Height;
+ image.bpp = 8;
+ image.delay = (s32)((float)flic.FrameDelay * 14.3);
+ finfo.animated = (currentImage) ? true : false;
+
+// prs32f("%dx%d@%d, delay: %d\n", flic.Width, flic.Height, flic.PixelDepth, finfo.image[currentImage].delay);
+
+ CHUNKHEADER chunk;
+ CHUNKHEADER subchunk;
+ u16 subchunks;
+
+ fstream::pos_type pos = frs.tellg();
+// prs32f("POS AFTER HEADER: %d\n", pos);
+
+ while(true)
+ {
+ if(!skip_flood(frs))
+ return SQE_R_BADFILE;
+
+ if(!frs.readK(&chunk, sizeof(CHUNKHEADER)))
+ return SQE_R_BADFILE;
+
+// prs32f("Read MAIN chunk: size: %d, type: %X\n", chunk.size, chunk.type);
+
+ if(chunk.type != CHUNK_PREFIX_TYPE &&
+ chunk.type != CHUNK_SCRIPT_CHUNK &&
+ chunk.type != CHUNK_FRAME_TYPE &&
+ chunk.type != CHUNK_SEGMENT_TABLE &&
+ chunk.type != CHUNK_HUFFMAN_TABLE)
+ return SQE_R_BADFILE;
+
+ if(chunk.type != CHUNK_FRAME_TYPE)
+ frs.seekg(chunk.size - sizeof(CHUNKHEADER), ios::cur);
+ else
+ {
+ if(!frs.readK(&subchunks, sizeof(u16)))
+ return SQE_R_BADFILE;
+// prs32f("Chunk #%X has %d subchunks\n", chunk.type, subchunks);
+ frs.seekg(sizeof(u16) * 4, ios::cur);
+ break;
+ }
+ }
+
+// prs32f("POS MAIN: %d\n", ftell(fptr));
+// fsetpos(fptr, (fpos_t*)&pos);
+// fseek(fptr, chunk.size, SEEK_CUR);
+// prs32f("POS2 MAIN: %d\n", ftell(fptr));
+
+ while(subchunks--)
+ {
+ pos = frs.tellg();
+
+ if(!frs.readK(&subchunk, sizeof(CHUNKHEADER)))
+ return SQE_R_BADFILE;
+
+// prs32f("*** Subchunk: %d\n", subchunk.type);
+
+ switch(subchunk.type)
+ {
+ case CHUNK_COLOR_64:
+ case CHUNK_COLOR_256:
+ {
+// prs32f("*** Palette64 CHUNK\n");
+ u8 skip, count;
+ u16 packets;
+ RGB e;
+
+ if(!frs.readK(&packets, sizeof(u16)))
+ return SQE_R_BADFILE;
+// prs32f("COLOR_64 packets: %d\n", packets);
+
+ for(s32 i = 0;i < packets;i++)
+ {
+ if(!frs.readK(&skip, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&count, 1)) return SQE_R_BADFILE;
+// prs32f("COLOR64 skip: %d, count: %d\n", skip, count);
+
+ if(count)
+ {
+ for(s32 j = 0;j < count;j++)
+ {
+ if(!frs.readK(&e, sizeof(RGB))) return SQE_R_BADFILE;
+// prs32f("COLOR_64 PALLETTE CHANGE %d,%d,%d\n", e.r, e.g, e.b);
+ }
+ }
+ else
+ {
+// prs32f("Reading pallette...\n");
+ if(!frs.readK(pal, sizeof(RGB) * 256)) return SQE_R_BADFILE;
+
+ u8 *pp = (u8 *)pal;
+
+ if(subchunk.type == CHUNK_COLOR_64)
+ for(s32 j = 0;j < 768;j++)
+ pp[j] <<= 2;
+
+// for(s32 j = 0;j < 256;j++)
+// prs32f("COLOR_64 PALLETTE %d,%d,%d\n", pal[j].r, pal[j].g, pal[j].b);
+// prs32f("\n");
+ }
+ }
+ }
+ break;
+
+ case CHUNK_RLE:
+ {
+// prs32f("*** RLE DATA CHUNK\n");
+ u8 value;
+ s8 c;
+ s32 count;
+
+ for(s32 j = 0;j < image.h;j++)
+ {
+ s32 index = 0;
+ count = 0;
+ if(!frs.readK(&c, 1)) return SQE_R_BADFILE;
+
+ while(count < image.w)
+ {
+ if(!frs.readK(&c, 1)) return SQE_R_BADFILE;
+
+ if(c < 0)
+ {
+ c = -c;
+
+ for(s32 i = 0;i < c;i++)
+ {
+ if(!frs.readK(&value, 1)) return SQE_R_BADFILE;
+ buf[j][index] = value;
+ index++;
+ }
+
+ count += c;
+ }
+ else
+ {
+ if(!frs.readK(&value, 1)) return SQE_R_BADFILE;
+
+ for(s32 i = 0;i < c;i++)
+ {
+ buf[j][index] = value;
+ index++;
+ }
+
+ count += c;
+ }
+ }
+ }
+ }
+ break;
+
+ case CHUNK_DELTA_FLI:
+ {
+ u16 starty, totaly, ally, index;
+ u8 packets, skip, byte;
+ s8 size;
+ s32 count;
+
+ if(!frs.readK(&starty, 2)) return SQE_R_BADFILE;
+ if(!frs.readK(&totaly, 2)) return SQE_R_BADFILE;
+
+ ally = starty + totaly;
+
+// prs32f("Y: %d, Total: %d\n", starty, totaly);
+
+ for(s32 j = starty;j < ally;j++)
+ {
+ count = 0;
+ index = 0;
+
+ if(!frs.readK(&packets, 1)) return SQE_R_BADFILE;
+
+ while(count < image.w)
+ {
+ for(s32 k = 0;k < packets;k++)
+ {
+// prs32f("LINE %d\n", j);
+ if(!frs.readK(&skip, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&size, 1)) return SQE_R_BADFILE;
+
+ index += skip;
+
+// prs32f("SKIP: %d, SIZE: %d\n", skip, size);
+
+ if(size > 0)
+ {
+ if(!frs.readK(buf[j]+index, size)) return SQE_R_BADFILE;
+ }
+ else if(size < 0)
+ {
+ size = -size;
+ if(!frs.readK(&byte, 1)) return SQE_R_BADFILE;
+ memset(buf[j]+index, byte, size);
+ }
+
+ index += size;
+ count += size;
+ }
+
+ break;
+ }
+ }
+ }
+ break;
+
+ case CHUNK_BLACK:
+ break;
+
+ case CHUNK_COPY:
+ {
+// prs32f("*** COPY DATA CHUNK\n");
+
+ for(s32 j = 0;j < image.h;j++)
+ {
+ if(!frs.readK(buf[j], image.w)) return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ default:
+// prs32f("*** UNKNOWN CHUNK! SEEKING ANYWAY\n");
+ frs.seekg(pos);
+ frs.seekg(subchunk.size, ios::cur);
+ }
+
+// prs32f("POS: %d\n", ftell(fptr));
+// prs32f("POS2: %d\n", ftell(fptr));
+ }
+
+ image.compression = "RLE/DELTA_FLI";
+ image.colorspace = "Color indexed";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ memcpy(scan+i, pal+buf[line][i], sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(buf)
+ {
+ for(s32 i = 0;i < flic.Height;i++)
+ if(buf[i])
+ free(buf[i]);
+
+ free(buf);
+ }
+
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool find_chunk_type(const u16 type)
+{
+ static const u16 A[] =
+ {
+ CHUNK_PREFIX_TYPE,
+ CHUNK_SCRIPT_CHUNK,
+ CHUNK_FRAME_TYPE,
+ CHUNK_SEGMENT_TABLE,
+ CHUNK_HUFFMAN_TABLE
+ };
+
+ static const s32 S = 5;
+
+ for(s32 i = 0;i < S;i++)
+ if(type == A[i])
+ return true;
+
+ return false;
+}
+
+bool fmt_codec::skip_flood(ifstreamK &s)
+{
+ u8 _f[4];
+ u16 b;
+ fstream::pos_type _pos;
+
+// prs32f("SKIP_FLOOD pos: %d\n", ftell(f));
+
+ if(!s.readK(_f, 4)) return false;
+
+ do
+ {
+ _pos = s.tellg();
+ if(!s.readK(&b, 2)) return false;
+// prs32f("SKIP_FLOOD b: %X\n", b);
+ s.seekg(-1, ios::cur);
+ }while(!find_chunk_type(b));
+
+ _pos -= 4;
+
+ s.seekg(_pos);
+
+ return true;
+
+// prs32f("SKIP_FLOOD pos2: %d\n", ftell(f));
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_fli/fmt_codec_fli_defs.h b/kernel/kls_fli/fmt_codec_fli_defs.h
new file mode 100644
index 0000000..dd08b94
--- /dev/null
+++ b/kernel/kls_fli/fmt_codec_fli_defs.h
@@ -0,0 +1,92 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_fli
+#define KSQUIRREL_READ_IMAGE_fli
+
+struct FLICHEADER
+{
+ u32 FileSize; /* Total size of file */
+ u16 FileId; /* File format indicator */
+ u16 NumberOfFrames; /* Total number of frames */
+ u16 Width; /* Screen width in pixels */
+ u16 Height; /* Screen height in pixels */
+ u16 PixelDepth; /* Number of bits per pixel */
+ u16 Flags; /* Set to 03h */
+ u32 FrameDelay; /* Time delay between frames */
+ u16 Reserved1; /* Not used (Set to 00h) */
+
+// The following fields are set to 00h in a .FLI file
+ u32 DateCreated; /* Time/Date the file was created */
+ u32 CreatorSN; /* Serial number of creator program */
+ u32 LastUpdated; /* Time/Date the file last changed */
+ u32 UpdaterSN; /* Serial number of updater program */
+ u16 XAspect; /* X-axis of display aspect ratio */
+ u16 YAspect; /* Y-axis of display aspect ratio */
+ u8 Reserved2[38]; /* Not used (Set to 00h) */
+ u32 Frame1Offset; /* Offset of first frame */
+ u32 Frame2Offset; /* Offset of second frame */
+ u8 Reserved3[40]; /* Not used (Set to 00h) */
+
+}PACKED;
+
+struct CHUNKHEADER
+{
+ u32 size; /* Total size of chunk */
+ u16 type; /* Chunk identifier */
+// u16 subchunks; /* Number of subchunks in this chunk */
+// u8 res[8]; /* Not used (Set to 00h) */
+
+}PACKED;
+
+#define CHUNK_CEL_DATA 3
+#define CHUNK_COLOR_256 4
+#define CHUNK_DELTA_FLC 7
+#define CHUNK_COLOR_64 11
+#define CHUNK_DELTA_FLI 12
+#define CHUNK_BLACK 13
+#define CHUNK_RLE 15
+#define CHUNK_COPY 16
+#define CHUNK_PSTAMP 18
+#define CHUNK_DTA_BRUN 25
+#define CHUNK_DTA_COPY 26
+#define CHUNK_DTA_LC 27
+#define CHUNK_LABEL 31
+#define CHUNK_BMP_MASK 32
+#define CHUNK_MLEV_MASK 33
+#define CHUNK_SEGMENT 34
+#define CHUNK_KEY_IMAGE 35
+#define CHUNK_KEY_PAL 36
+#define CHUNK_REGION 37
+#define CHUNK_WAVE 38
+#define CHUNK_USERSTR 39
+#define CHUNK_RGN_MASK 40
+#define CHUNK_LABELEX 41
+#define CHUNK_SHIFT 42
+#define CHUNK_PATHMAP 43
+
+#define CHUNK_PREFIX_TYPE 0xF100
+#define CHUNK_SCRIPT_CHUNK 0xF1E0
+#define CHUNK_FRAME_TYPE 0xF1FA
+#define CHUNK_SEGMENT_TABLE 0xF1FB
+#define CHUNK_HUFFMAN_TABLE 0xF1FC
+
+#endif
diff --git a/kernel/kls_gif/Makefile.am b/kernel/kls_gif/Makefile.am
new file mode 100644
index 0000000..62f5ed5
--- /dev/null
+++ b/kernel/kls_gif/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_gif.la
+
+libkls_gif_la_SOURCES = fmt_codec_gif.cpp fmt_codec_gif_defs.h
+
+libkls_gif_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_gif_la_LIBADD = ${SQ_LOCAL_RPATH} ${SQ_GIFLIBS}
diff --git a/kernel/kls_gif/fmt_codec_gif.cpp b/kernel/kls_gif/fmt_codec_gif.cpp
new file mode 100644
index 0000000..80f2dbb
--- /dev/null
+++ b/kernel/kls_gif/fmt_codec_gif.cpp
@@ -0,0 +1,516 @@
+/* This file is part of the ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004,2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License (LGPL) as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_gif_defs.h"
+
+extern "C" {
+#include "gif_lib.h"
+}
+
+#include "fmt_codec_gif.h"
+
+#include "../xpm/codec_gif.xpm"
+
+/*
+ *
+ * Originally designed to facilitate image transfer and online
+ * storage for use by CompuServe and its customers,
+ * GIF is primarily an exchange and storage
+ * format, although it is based on, and is supported by, many
+ * applications.
+ *
+ */
+
+static s32
+InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
+InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "1.3.1";
+ o->name = "Compuserve GIF";
+ o->filter = "*.gif ";
+ o->config = "";
+ o->mime = "\x0047\x0049\x0046\x0038[\x0039\x0037]\x0061";
+ o->mimetype = "image/gif";
+ o->pixmap = codec_gif;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ frs.close();
+
+ transIndex = -1;
+
+ Last = 0;
+ Lines = 0;
+ buf = 0;
+ saved = 0;
+
+ gif = DGifOpenFileName(file.c_str());
+
+ // for safety...
+ if(!gif)
+ return SQE_R_BADFILE;
+
+ linesz = gif->SWidth * sizeof(GifPixelType);
+
+ if((buf = (u8*)malloc(linesz)) == NULL)
+ return SQE_R_NOMEMORY;
+
+ if((saved = (RGBA *)calloc(linesz, sizeof(RGBA))) == NULL)
+ return SQE_R_NOMEMORY;
+
+ if(gif->SColorMap)
+ {
+ back.r = gif->SColorMap->Colors[gif->SBackGroundColor].Red;
+ back.g = gif->SColorMap->Colors[gif->SBackGroundColor].Green;
+ back.b = gif->SColorMap->Colors[gif->SBackGroundColor].Blue;
+ back.a = 255;
+ }
+ else
+ memset(&back, 0, sizeof(RGBA));
+
+ layer = -1;
+ line = 0;
+ curLine = 0;
+
+ Lines_h = gif->SHeight;
+ Lines = (RGBA **)malloc(Lines_h * sizeof(RGBA*));
+
+ if(!Lines)
+ return SQE_R_NOMEMORY;
+
+ for(s32 i = 0;i < Lines_h;i++)
+ Lines[i] = (RGBA *)0;
+
+ map = (gif->Image.ColorMap) ? gif->Image.ColorMap : gif->SColorMap;
+
+ Last = (RGBA **)malloc(gif->SHeight * sizeof(RGBA*));
+
+ if(!Last)
+ return SQE_R_NOMEMORY;
+
+ for(s32 i = 0;i < gif->SHeight;i++)
+ Last[i] = (RGBA *)0;
+
+ for(s32 i = 0;i < gif->SHeight;i++)
+ {
+ Last[i] = (RGBA *)calloc(gif->SWidth, sizeof(RGBA));
+
+ if(!Last[i])
+ return SQE_R_NOMEMORY;
+
+// for(s32 k = 0;k < gif->SWidth;k++)
+// memcpy(Last[i]+k, &back, sizeof(RGBA));
+ }
+
+ currentImage = -1;
+ lastDisposal = DISPOSAL_NO;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ layer++;
+ currentPass++;
+ line = 0;
+ curLine = 0;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ bool foundExt = false;
+
+ currentImage++;
+
+ fmt_image image;
+
+ image.interlaced = gif->Image.Interlace;
+ image.passes = (gif->Image.Interlace) ? 4 : 1;
+
+ while(true)
+ {
+ if (DGifGetRecordType(gif, &record) == GIF_ERROR)
+ {
+ PrintGifError();
+ return SQE_R_BADFILE;
+ }
+
+ switch(record)
+ {
+ case IMAGE_DESC_RECORD_TYPE:
+ if(DGifGetImageDesc(gif) == GIF_ERROR)
+ {
+ PrintGifError();
+ return SQE_R_BADFILE;
+ }
+
+ if(!foundExt)
+ {
+ lastDisposal = disposal;
+ disposal = DISPOSAL_NO;
+ image.delay = 100;
+ transIndex = -1;
+ image.hasalpha = true;
+ }
+
+ lastRow = (currentImage) ? Row : gif->Image.Top;
+ lastCol = (currentImage) ? Col : gif->Image.Left;
+ Row = gif->Image.Top;
+ Col = gif->Image.Left;
+ image.w = gif->SWidth;
+ image.h = gif->SHeight;
+ lastWidth = (currentImage) ? Width : gif->Image.Width;
+ lastHeight = (currentImage) ? Height : gif->Image.Height;
+ Width = gif->Image.Width;
+ Height = gif->Image.Height;
+ image.bpp = 8;
+
+ curLine = 0;
+
+ if(gif->Image.Left + gif->Image.Width > gif->SWidth || gif->Image.Top + gif->Image.Height > gif->SHeight)
+ {
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case EXTENSION_RECORD_TYPE:
+ if(DGifGetExtension(gif, &ExtCode, &Extension) == GIF_ERROR)
+ {
+ PrintGifError();
+ return SQE_R_BADFILE;
+ }
+
+ if(!Extension)
+ break;
+
+ if(ExtCode == 249)
+ {
+ foundExt = true;
+
+ lastDisposal = disposal;
+ disposal = (Extension[1] >> 2) & 7;
+ bool b = Extension[1] & 1;
+ s32 u = (unsigned)*(Extension + 2);
+ image.delay = (!u) ? 100 : (u * 10);
+
+ if(b)
+ transIndex = Extension[4];
+
+ image.hasalpha = b;
+ }
+ else if(ExtCode == 254 && Extension[0])
+ {
+ fmt_metaentry mt;
+ s8 d[Extension[0]+1];
+
+ memcpy(d, (s8*)Extension+1, Extension[0]);
+ d[Extension[0]] = '\0';
+
+ for(s32 s = 0;s < Extension[0];s++)
+ if(d[s] == '\n')
+ d[s] = ' ';
+
+ mt.group = "Comment";
+ mt.data = d;
+
+ addmeta(mt);
+ }
+
+ while(Extension)
+ {
+ if(DGifGetExtensionNext(gif, &Extension) == GIF_ERROR)
+ {
+ PrintGifError();
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case TERMINATE_RECORD_TYPE:
+ return SQE_NOTOK;
+
+ default: ;
+ }
+
+ if(record == IMAGE_DESC_RECORD_TYPE)
+ {
+ if(currentImage >= 1)
+ finfo.animated = true;
+
+ map = (gif->Image.ColorMap) ? gif->Image.ColorMap : gif->SColorMap;
+
+ back.a = (transIndex != -1) ? 0 : 255;
+
+ for(s32 k = 0;k < gif->SWidth;k++)
+ memcpy(saved+k, &back, sizeof(RGBA));
+
+ image.compression = "LZW";
+ image.colorspace = "Color indexed";
+ image.interlaced = gif->Image.Interlace;
+ image.passes = (gif->Image.Interlace) ? 4 : 1;
+
+ finfo.image.push_back(image);
+
+ layer = -1;
+ currentPass = -1;
+
+ return SQE_OK;
+ }
+ }
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ if(curLine < Row || curLine >= Row + Height)
+ {
+ if(currentPass == im->passes-1)
+ {
+ memcpy(scan, Last[curLine], im->w * sizeof(RGBA));
+
+ if(lastDisposal == DISPOSAL_BACKGROUND)
+ if(curLine >= lastRow && curLine < lastRow+lastHeight)
+ {
+ memcpy(scan+lastCol, saved, lastWidth * sizeof(RGBA));
+ memcpy(Last[curLine], scan, im->w * sizeof(RGBA));
+ }
+ }
+
+ curLine++;
+
+ return SQE_OK;
+ }
+
+ curLine++;
+
+ s32 i;
+ s32 index;
+
+ if(gif->Image.Interlace)
+ {
+ memcpy(scan, Last[curLine-1], im->w * sizeof(RGBA));
+
+ if(line == 0)
+ j = InterlacedOffset[layer];
+
+ if(line == j)
+ {
+ if(DGifGetLine(gif, buf, Width) == GIF_ERROR)
+ {
+ PrintGifError();
+ memset(scan, 255, im->w * sizeof(RGBA));
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ j += InterlacedJumps[layer];
+
+ for(i = 0;i < Width;i++)
+ {
+ index = Col + i;
+
+ if(buf[i] == transIndex && transIndex != -1)
+ {
+ RGB rgb = *((RGB *)&(map->Colors[buf[i]]));
+
+ if(back == rgb && !currentImage)
+ (scan+index)->a = 0;
+ else if(back == rgb && lastDisposal != DISPOSAL_BACKGROUND && currentImage)
+ {
+ RGBA *t = &Last[curLine-1][index];
+ memcpy(scan+index, t, sizeof(RGBA));
+ }
+ else if(back == rgb && lastDisposal == DISPOSAL_BACKGROUND && currentImage)
+ {
+ (scan+index)->a = 0;
+ }
+ else if(currentImage)
+ {
+ RGBA *t = &Last[curLine-1][index];
+
+ if(lastDisposal == DISPOSAL_BACKGROUND)
+ {
+ memcpy(scan+index, &back, sizeof(RGBA));//(scan+index)->a=0;
+
+ if(t->a == 0)
+ (scan+index)->a=0;
+ }
+ }
+ }
+ else
+ {
+ memcpy(scan+index, &(map->Colors[buf[i]]), sizeof(RGB));
+ (scan+index)->a = 255;
+ }
+ }
+
+ Lines[line] = (RGBA*)realloc(Lines[line], im->w * sizeof(RGBA));
+
+ if(!Lines[line])
+ return SQE_R_NOMEMORY;
+
+ memcpy(Lines[line], scan, im->w * sizeof(RGBA));
+ }
+ } // if(line == j)
+ else
+ {
+ if(Lines[line])
+ memcpy(scan, Lines[line], im->w * sizeof(RGBA));
+ else
+ memset(scan, 255, im->w * sizeof(RGBA));
+ }
+
+ if(currentPass == im->passes-1)
+ memcpy(Last[curLine-1], scan, im->w * sizeof(RGBA));
+
+ line++;
+ }
+ else // !s32erlaced
+ {
+ if(DGifGetLine(gif, buf, Width) == GIF_ERROR)
+ {
+ memset(scan, 255, im->w * sizeof(RGBA));
+ PrintGifError();
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ memcpy(scan, Last[curLine-1], im->w * sizeof(RGBA));
+
+ if(lastDisposal == DISPOSAL_BACKGROUND)
+ {
+ if(curLine-1 >= lastRow && curLine-1 < lastRow+lastHeight)
+ memcpy(scan+lastCol, saved, lastWidth * sizeof(RGBA));
+ }
+
+ for(i = 0;i < Width;i++)
+ {
+ index = Col + i;
+
+ if(buf[i] == transIndex && transIndex != -1)
+ {
+ RGB rgb = *((RGB *)&(map->Colors[buf[i]]));
+
+ if(back == rgb && !currentImage)
+ (scan+index)->a = 0;
+ else if(back == rgb && lastDisposal != DISPOSAL_BACKGROUND && currentImage)
+ {
+ RGBA *t = &Last[curLine-1][index];
+ memcpy(scan+index, t, sizeof(RGBA));// = 255;
+ }
+ else if(back == rgb && lastDisposal == DISPOSAL_BACKGROUND && currentImage)
+ {
+ (scan+index)->a = 0;
+ }
+ else if(currentImage)
+ {
+ RGBA *t = &Last[curLine-1][index];
+
+ if(lastDisposal == DISPOSAL_BACKGROUND)
+ {
+ memcpy(scan+index, &back, sizeof(RGBA));//(scan+index)->a=0;
+
+ if(t->a == 0)
+ (scan+index)->a=0;
+ }
+ }
+ }// if transIndex
+ else
+ {
+ memcpy(scan+index, &(map->Colors[buf[i]]), sizeof(RGB));
+ (scan+index)->a = 255;
+ }
+ } // for
+
+ memcpy(Last[curLine-1], scan, im->w * sizeof(RGBA));
+ }
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(buf) free(buf);
+ if(saved) free(saved);
+
+ if(Lines)
+ {
+ for(s32 i = 0;i < Lines_h;i++)
+ if(Lines[i])
+ free(Lines[i]);
+
+ free(Lines);
+ Lines = 0;
+ }
+
+ if(Last)
+ {
+ for(s32 i = 0;i < gif->SHeight;i++)
+ if(Last[i])
+ free(Last[i]);
+
+ free(Last);
+ Last = 0;
+ }
+
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ if(gif) DGifCloseFile(gif);
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_gif/fmt_codec_gif_defs.h b/kernel/kls_gif/fmt_codec_gif_defs.h
new file mode 100644
index 0000000..02b4f41
--- /dev/null
+++ b/kernel/kls_gif/fmt_codec_gif_defs.h
@@ -0,0 +1,32 @@
+/* This file is part of the ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License (LGPL) as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_gif
+#define KSQUIRREL_READ_IMAGE_gif
+
+#define SQ_NEED_OPERATOR_RGBA_RGB
+
+#define DISPOSAL_NO 0
+#define DISPOSAL_LEFT 1
+#define DISPOSAL_BACKGROUND 2
+#define DISPOSAL_PREVIOUS 3
+
+#endif
diff --git a/kernel/kls_hdr/Makefile.am b/kernel/kls_hdr/Makefile.am
new file mode 100644
index 0000000..3c76848
--- /dev/null
+++ b/kernel/kls_hdr/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_hdr.la
+
+libkls_hdr_la_SOURCES = fmt_codec_hdr.cpp fmt_codec_hdr_defs.h
+
+libkls_hdr_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_hdr_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_hdr/fmt_codec_hdr.cpp b/kernel/kls_hdr/fmt_codec_hdr.cpp
new file mode 100644
index 0000000..9819504
--- /dev/null
+++ b/kernel/kls_hdr/fmt_codec_hdr.cpp
@@ -0,0 +1,332 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_hdr_defs.h"
+#include "fmt_codec_hdr.h"
+
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "../xpm/codec_hdr.xpm"
+
+/*
+ *
+ * Radiance HDR image
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "Radiance HDR image";
+ o->filter = "*.hdr ";
+ o->config = "";
+ o->mime = "#.RADIANCE";
+ o->mimetype = "image/x-hdr";
+ o->pixmap = codec_hdr;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ scanline = 0;
+
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ if(!getHdrHead()) return SQE_R_BADFILE;
+
+ if(strcmp(hdr.sig, "#?RADIANCE")) return SQE_R_BADFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ image.w = hdr.width;
+ image.h = hdr.height;
+ image.bpp = 32;
+
+ scanline = new u8 [hdr.width * sizeof(RGBA)];
+
+ if(!scanline) return SQE_R_NOMEMORY;
+
+ image.compression = "RGBE";
+ image.colorspace = fmt_utils::colorSpaceByBpp(32);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u32 r, g, b, e, i, j;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ if(!read_scan(scanline, im->w))
+ return SQE_R_BADFILE;
+
+ for(j = 0, i = 0; j < (u32)im->w * 4; j += 4, i++)
+ {
+ float t;
+
+ e = scanline[j + 3];
+ r = scanline[j + 0];
+ g = scanline[j + 1];
+ b = scanline[j + 2];
+
+ //t = (float)pow(2.f, ((ILint)e) - 128);
+ if (e != 0)
+ e = (e - 1) << 23;
+
+ t = *(float *)&e;
+
+ (scan + i)->r = u8((r / 255.0f) * t);
+ (scan + i)->g = u8((g / 255.0f) * t);
+ (scan + i)->b = u8((b / 255.0f) * t);
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ delete [] scanline;
+ scanline = 0;
+}
+
+//
+// These two methods were taken from DevIL
+// http://imagelib.org
+//
+
+bool fmt_codec::read_scan(u8 *scanline, const s32 w)
+{
+ u8 *runner, c;
+ u32 r, g, b, e, read, shift;
+
+ if(!frs.readK(&c, sizeof(u8))) return false; r = c;
+ if(!frs.readK(&c, sizeof(u8))) return false; g = c;
+ if(!frs.readK(&c, sizeof(u8))) return false; b = c;
+ if(!frs.readK(&c, sizeof(u8))) return false; e = c;
+
+ //check if the scanline is in the new format
+ //if so, e, r, g, g are stored separated and are
+ //rle-compressed independently.
+ if (r == 2 && g == 2)
+ {
+ u32 length = (b << 8) | e;
+ u32 j, t, k;
+
+ if (length > (u32)w)
+ length = w; //fix broken files
+
+ for(k = 0; k < 4; ++k)
+ {
+ runner = scanline + k;
+ j = 0;
+
+ while (j < length)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return false;
+
+ t = c;
+
+ if(t > 128)
+ { //Run?
+ if(!frs.readK(&c, sizeof(u8))) return false;
+
+ t &= 127;
+
+ //copy current byte
+ while (t > 0 && j < length)
+ {
+ *runner = c;
+ runner += 4;
+ --t;
+ ++j;
+ }
+ }
+ else
+ { //No Run.
+ //read new bytes
+ while (t > 0 && j < length)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return false;
+
+ *runner = c;
+ runner += 4;
+ --t;
+ ++j;
+ }
+ }
+ }
+ }
+
+ return true; //done decoding a scanline in separated format
+ }
+
+ //if we come here, we are dealing with old-style scanlines
+ shift = 0;
+ read = 0;
+ runner = scanline;
+
+ while(read < (u32)w)
+ {
+ if (read != 0)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return false; r = c;
+ if(!frs.readK(&c, sizeof(u8))) return false; g = c;
+ if(!frs.readK(&c, sizeof(u8))) return false; b = c;
+ if(!frs.readK(&c, sizeof(u8))) return false; e = c;
+ }
+
+ //if all three mantissas are 1, then this is a rle
+ //count dword
+ if (r == 1 && g == 1 && b == 1)
+ {
+ u32 length = e;
+ u32 j;
+
+ for (j = length << shift; j > 0; --j)
+ {
+ memcpy(runner, runner - 4, 4);
+ runner += 4;
+ }
+ //if more than one rle count dword is read
+ //consecutively, they are higher order bytes
+ //of the first read value. shift keeps track of
+ //that.
+ shift += 8;
+ read += length;
+ }
+ else
+ {
+ runner[0] = r;
+ runner[1] = g;
+ runner[2] = b;
+ runner[3] = e;
+
+ shift = 0;
+ runner += 4;
+ ++read;
+ }
+ }
+
+ return true;
+}
+
+bool fmt_codec::getHdrHead()
+{
+ bool done = false;
+ s8 a, b;
+ s8 x[2], y[2];
+ s8 buff[80];
+ u32 count = 0;
+
+ if(!frs.readK(hdr.sig, sizeof(hdr.sig)-1)) return false;
+
+ hdr.sig[10] = '\0';
+
+ //skip lines until an empty line is found.
+ //this marks the end of header information,
+ //the next line contains the image's dimension.
+
+ //TODO: read header contents into variables
+ //(EXPOSURE, orientation, xyz correction, ...)
+
+ if(!frs.readK(&a, sizeof(s8)))
+ return false;
+
+ while(!done)
+ {
+ if(!frs.readK(&b, sizeof(s8))) return false;
+
+ if (b == '\n' && a == '\n')
+ done = true;
+ else
+ a = b;
+ }
+
+ //read dimensions (note that this assumes a somewhat valid image)
+ if(!frs.readK(&a, sizeof(s8))) return false;
+
+ while (a != '\n')
+ {
+ buff[count] = a;
+
+ if(!frs.readK(&a, sizeof(s8))) return false;
+
+ ++count;
+ }
+
+ buff[count] = '\0';
+
+ sscanf(buff, "%s %d %s %d", x, &hdr.width, y, &hdr.height);
+
+ return true;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_hdr/fmt_codec_hdr_defs.h b/kernel/kls_hdr/fmt_codec_hdr_defs.h
new file mode 100644
index 0000000..7689c06
--- /dev/null
+++ b/kernel/kls_hdr/fmt_codec_hdr_defs.h
@@ -0,0 +1,32 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_hdr
+#define KSQUIRREL_CODEC_DEFS_hdr
+
+struct hdr_header
+{
+ s8 sig[11]; //must be "#?RADIANCE"
+ s32 width, height;
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_ico/Makefile.am b/kernel/kls_ico/Makefile.am
new file mode 100644
index 0000000..d81b368
--- /dev/null
+++ b/kernel/kls_ico/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_ico.la
+
+libkls_ico_la_SOURCES = fmt_codec_ico.cpp fmt_codec_ico_defs.h
+
+libkls_ico_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_ico_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_ico/fmt_codec_ico.cpp b/kernel/kls_ico/fmt_codec_ico.cpp
new file mode 100644
index 0000000..af6a2f7
--- /dev/null
+++ b/kernel/kls_ico/fmt_codec_ico.cpp
@@ -0,0 +1,296 @@
+/* This file is part of ksquirrel (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_ico_defs.h"
+#include "fmt_codec_ico.h"
+
+#include "../xpm/codec_ico.xpm"
+
+/*
+ *
+ * An icon-resource file contains image data for icons used by Windows
+ * applications. The file consists of an icon directory identifying the number
+ * and types of icon images in the file, plus one or more icon images. The
+ * default filename extension for an icon-resource file is .ICO.
+ *
+*/
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.4.2";
+ o->name = "Windows icons";
+ o->filter = "*.ico *.cur ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-ico";
+ o->pixmap = codec_ico;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ pal_entr = 0;
+ bAND = 0;
+
+ if(!frs.readK(&ifh, sizeof(ICO_HEADER)))
+ return SQE_R_BADFILE;
+
+ if(ifh.idType != 1 && ifh.idType != 2)
+ return SQE_R_BADFILE;
+
+ ide = (ICO_DIRENTRY*)calloc(ifh.idCount, sizeof(ICO_DIRENTRY));
+
+ if(!ide)
+ return SQE_R_NOMEMORY;
+
+ if(!frs.readK(ide, sizeof(ICO_DIRENTRY) * ifh.idCount))
+ return SQE_R_BADFILE;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == ifh.idCount)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ RGBA rgba;
+ s32 i;
+ fstream::pos_type pos;
+
+ image.w = ide[currentImage].bWidth;
+ image.h = ide[currentImage].bHeight;
+
+ frs.seekg(ide[currentImage].dwImageOffset, ios::beg);
+
+ if(!frs.readK(&bih, sizeof(BITMAPINFO_HEADER)))
+ return SQE_R_BADFILE;
+
+ image.bpp = bih.BitCount;
+
+ if(image.bpp < 16)
+ {
+ pal_entr = 1 << image.bpp;
+
+ for(i = 0;i < pal_entr;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ pal[i].r = rgba.b;
+ pal[i].g = rgba.g;
+ pal[i].b = rgba.r;
+ }
+ }
+ else
+ {
+ pal_entr = 0;
+ }
+
+ pos = frs.tellg();
+
+ s32 count = image.w * image.h;
+ s32 count2 = (image.bpp < 16) ? (count / (8 / image.bpp)) : (count * (image.bpp / 8));
+ s32 count3 = count / 8;
+
+ frs.seekg(/*ide[currentImage].dwBytes - sizeof(BITMAPINFO_HEADER) - */count2, ios::cur);
+
+ bAND = (u8 *)realloc(bAND, count * sizeof(u8));
+
+ if(!bAND)
+ return SQE_R_NOMEMORY;
+
+ u8 realAND[count3];
+
+ if(!frs.readK(realAND, count3)) return SQE_R_BADFILE;
+
+ s32 r = 0;
+
+ for(i = 0;i < count3;i++)
+ {
+ for(s32 z = 0,f = 128;z < 8;z++,f >>= 1)
+ {
+ bAND[r] = (realAND[i] & f) ? 1 : 0;
+ r++;
+ }
+ }
+
+ frs.seekg(pos);
+
+ image.needflip = true;
+ image.hasalpha = true;
+
+ image.compression = "-";
+ image.colorspace = ((pal_entr) ? "Color indexed":"RGB");
+
+ finfo.image.push_back(image);
+
+ pixel = 0;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ s32 i, j, count;
+ u8 bt, ind;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(im->bpp)
+ {
+ case 1:
+ j = im->w / 8;
+ count = 0;
+
+ for(i = 0;i < j;i++)
+ {
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ for(s32 z = 0, f = 128;z < 8;z++,f >>= 1)
+ {
+ ind = (bt & f) ? 1 : 0;
+
+ memcpy(scan+count, pal+ind, sizeof(RGB));
+
+ count++;
+ pixel++;
+ }
+ }
+ break;
+
+ case 4:
+ j = 0;
+ do
+ {
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ ind = bt >> 4;
+ memcpy(scan+j, pal+ind, sizeof(RGB));
+// (scan+j)->a = (bAND[pixel]) ? 0 : 255;
+ j++;
+ pixel++;
+ ind = bt&15;
+ memcpy(scan+j, pal+ind, sizeof(RGB));
+// (scan+j)->a = (bAND[pixel]) ? 0 : 255;
+ j++;
+ pixel++;
+ }while(j < im->w);
+
+ break;
+
+ case 8:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, pal+bt, sizeof(RGB));
+// (scan+i)->a = (bAND[pixel]) ? 0 : 255;
+ pixel++;
+ }
+ break;
+
+ case 24:
+ {
+ RGB rgb;
+
+ for(i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ (scan+i)->r = rgb.b;
+ (scan+i)->g = rgb.g;
+ (scan+i)->b = rgb.r;
+ pixel++;
+ }
+ }
+ break;
+
+ case 32:
+ {
+ RGBA rgba;
+
+ for(i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ (scan+i)->r = rgba.b;
+ (scan+i)->g = rgba.g;
+ (scan+i)->b = rgba.r;
+ (scan+i)->a = rgba.a;
+ pixel++;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ if(bAND)
+ free(bAND);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_ico/fmt_codec_ico_defs.h b/kernel/kls_ico/fmt_codec_ico_defs.h
new file mode 100644
index 0000000..996f40e
--- /dev/null
+++ b/kernel/kls_ico/fmt_codec_ico_defs.h
@@ -0,0 +1,63 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_ico
+#define KSQUIRREL_READ_IMAGE_ico
+
+struct ICO_DIRENTRY
+{
+ u8 bWidth;
+ u8 bHeight;
+ u8 bColorCount;
+ u8 bReserved; /* 0 */
+ u16 wPlanes; /* 0 */
+ u16 wBitCount; /* 0 */
+ u32 dwBytes;
+ u32 dwImageOffset;
+
+}PACKED;
+
+
+struct ICO_HEADER
+{
+ u16 idReserved;
+ u16 idType; /* must be 1 */
+ u16 idCount;
+
+}PACKED;
+
+struct BITMAPINFO_HEADER
+{
+ u32 Size;
+ u32 Width;
+ u32 Height;
+ u16 Planes;
+ u16 BitCount;
+ u32 Compression; /* not used -->> */
+ u32 SizeImage;
+ u32 XPelsPerMeter;
+ u32 YPelsPerMeter;
+ u32 ClrUsed;
+ u32 ClrImportant;
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_iff/Makefile.am b/kernel/kls_iff/Makefile.am
new file mode 100644
index 0000000..8b52a35
--- /dev/null
+++ b/kernel/kls_iff/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-iff2ppm
+
+pkglib_LTLIBRARIES = libkls_iff.la
+
+libkls_iff_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_iff_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_iff_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_IFF -DNETPBM_S=\"${bindir}/ksquirrel-libs-iff2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-iff2ppm.in \ No newline at end of file
diff --git a/kernel/kls_iff/fmt_codec_pnm.cpp b/kernel/kls_iff/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_iff/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_iff/fmt_codec_pnm_defs.h b/kernel/kls_iff/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_iff/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_iff/ksquirrel-libs-iff2ppm.in b/kernel/kls_iff/ksquirrel-libs-iff2ppm.in
new file mode 100644
index 0000000..34b68f0
--- /dev/null
+++ b/kernel/kls_iff/ksquirrel-libs-iff2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@ILBMTOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_jbig/Makefile.am b/kernel/kls_jbig/Makefile.am
new file mode 100644
index 0000000..a74686f
--- /dev/null
+++ b/kernel/kls_jbig/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = libjbig
+
+INCLUDES = -I../include -Ilibjbig
+
+pkglib_LTLIBRARIES = libkls_jbig.la
+
+libkls_jbig_la_SOURCES = fmt_codec_jbig.cpp fmt_codec_jbig_defs.h jbig2mem.cpp jbig2mem.h
+
+libkls_jbig_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_jbig_la_LIBADD = ${SQ_LOCAL_RPATH} -Llibjbig -ljbig \ No newline at end of file
diff --git a/kernel/kls_jbig/fmt_codec_jbig.cpp b/kernel/kls_jbig/fmt_codec_jbig.cpp
new file mode 100644
index 0000000..d1cfa81
--- /dev/null
+++ b/kernel/kls_jbig/fmt_codec_jbig.cpp
@@ -0,0 +1,148 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_jbig_defs.h"
+#include "fmt_codec_jbig.h"
+
+#include "../xpm/codec_jbig.xpm"
+
+#include "jbig2mem.h"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.1";
+ o->name = "JBIG";
+ o->filter = "*.jbg *.jbig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-jbig";
+ o->pixmap = codec_jbig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ frs.close();
+
+ const char *argv[2] =
+ {
+ file.c_str(),
+ tmp.c_str()
+ };
+
+ if(jbig2mem((char **)argv))
+ return SQE_R_NOMEMORY;
+
+ frs.open(tmp.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ u32 w, h, bpp;
+ frs.readK(&w, sizeof(u32));
+ frs.readK(&h, sizeof(u32));
+ frs.readK(&bpp, sizeof(u32));
+
+ if(bpp != 24)
+ return SQE_R_BADFILE;
+
+ image.w = w;
+ image.h = h;
+ image.bpp = bpp;
+
+ image.compression = "?";
+ image.colorspace = fmt_utils::colorSpaceByBpp(1);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ frs.readK(&rgb, sizeof(RGB));
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_jbig/fmt_codec_jbig_defs.h b/kernel/kls_jbig/fmt_codec_jbig_defs.h
new file mode 100644
index 0000000..9f9a5bc
--- /dev/null
+++ b/kernel/kls_jbig/fmt_codec_jbig_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_jbig
+#define KSQUIRREL_CODEC_DEFS_jbig
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_jbig/jbig2mem.cpp b/kernel/kls_jbig/jbig2mem.cpp
new file mode 100644
index 0000000..9ae1abf
--- /dev/null
+++ b/kernel/kls_jbig/jbig2mem.cpp
@@ -0,0 +1,270 @@
+/*
+ * jbgtopbm - JBIG to Portable Bitmap converter
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ *
+ * $Id: jbgtopbm.c,v 1.11 2004-06-11 15:17:49+01 mgk25 Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "jbig.h"
+
+double koeff = 1.0;
+
+void write_it(unsigned char *data, size_t len, void *file)
+{
+ int bb;
+ unsigned char cc;
+
+ FILE *ff = (FILE *)file;
+
+ for(size_t i = 0;i < len;i++)
+ {
+ bb = int(koeff * (*(data+i)));
+
+ if(bb > 255) cc = 255;
+ else cc = bb;
+
+ fwrite(&cc, 1, 1, ff);
+ fwrite(&cc, 1, 1, ff);
+ fwrite(&cc, 1, 1, ff);
+ }
+}
+
+int read_file(unsigned char **buf, size_t *buflen, size_t *len, FILE *f)
+{
+ if (*buflen == 0) {
+ *buflen = 4000;
+ *len = 0;
+ *buf = (unsigned char *) malloc(*buflen);
+ if (!*buf) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ return 0;
+ }
+ }
+ do {
+ *len += fread(*buf + *len, 1, *buflen - *len, f);
+ if (*len == *buflen) {
+ *buflen *= 2;
+ *buf = (unsigned char *) realloc(*buf, *buflen);
+ if (!*buf) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ return 0;
+ }
+ }
+ if (ferror(f)) {
+ perror("Problem while reading input file");
+ return 0;
+ }
+ } while (!feof(f));
+ *buflen = *len;
+ *buf = (unsigned char *) realloc(*buf, *buflen);
+ if (!*buf) {
+ fprintf(stderr, "Oops, realloc failed when shrinking buffer!\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+int jbig2mem (char *argv[])
+{
+ FILE *fin = stdin, *fout = stdout;
+ const char *fnin = NULL, *fnout = NULL;
+ int i, result;
+ struct jbg_dec_state s;
+ unsigned char *buffer, *p;
+ size_t buflen, len, cnt;
+ unsigned long xmax = 4294967295UL, ymax = 4294967295UL, max;
+ int plane = -1, use_graycode = 1, multi = 0;
+
+printf("+JBIG %s, %s\n", argv[0], argv[1]);
+
+ buflen = 8000;
+ buffer = (unsigned char *) malloc(buflen);
+ if (!buffer) {
+ return 1;
+ }
+
+fnin = argv[0];
+fnout = argv[1];
+
+ fin = fopen(fnin, "rb");
+ if (!fin) {
+ free(buffer);
+ return 1;
+ }
+
+ fout = fopen(fnout, "wb");
+ if (!fout) {
+ fclose(fin);
+ free(buffer);
+ return 1;
+ }
+
+ /* send input file to decoder */
+ jbg_dec_init(&s);
+ jbg_dec_maxsize(&s, xmax, ymax);
+ /* read BIH first to check VLENGTH */
+ len = fread(buffer, 1, 20, fin);
+
+ if(len < 20)
+ {
+ fclose(fin);
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+
+ if (buffer[19] & JBG_VLENGTH) {
+ /* VLENGTH = 1 => we might encounter a NEWLEN, therefore read entire
+ * input file into memory and run two passes over it */
+ if(!read_file(&buffer, &buflen, &len, fin))
+ {
+ fclose(fin);
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+ /* scan for NEWLEN marker segments and update BIE header accordingly */
+ result = jbg_newlen(buffer, len);
+ /* feed data to decoder */
+ if (result == JBG_EOK) {
+ p = (unsigned char *) buffer;
+ result = JBG_EAGAIN;
+ while (len > 0 &&
+ (result == JBG_EAGAIN || (result == JBG_EOK && multi))) {
+ result = jbg_dec_in(&s, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ }
+ }
+ } else {
+ /* VLENGTH = 0 => we can simply pass the input file directly to decoder */
+ result = JBG_EAGAIN;
+ do {
+ cnt = 0;
+ p = (unsigned char *) buffer;
+ while (len > 0 &&
+ (result == JBG_EAGAIN || (result == JBG_EOK && multi))) {
+ result = jbg_dec_in(&s, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ }
+ if (!(result == JBG_EAGAIN || (result == JBG_EOK && multi)))
+ break;
+ len = fread(buffer, 1, buflen, fin);
+ } while (len > 0);
+
+ if (ferror(fin)) {
+ fclose(fin);
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+ }
+ if (result != JBG_EOK && result != JBG_EOK_INTR) {
+ fprintf(stderr, "Problem with input file '%s': %s\n",
+ fnin, jbg_strerror(result, JBG_EN));
+
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+ if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) {
+ fprintf(stderr, "Image has only %d planes!\n", jbg_dec_getplanes(&s));
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+
+ if (jbg_dec_getplanes(&s) == 1 || plane >= 0)
+ {
+ int w, h, bpp = 24;
+
+ w = jbg_dec_getwidth(&s);
+ h = jbg_dec_getheight(&s);
+
+ fwrite(&w, sizeof(int), 1, fout);
+ fwrite(&h, sizeof(int), 1, fout);
+ fwrite(&bpp, sizeof(int), 1, fout);
+
+ unsigned char *d = jbg_dec_getimage(&s, plane < 0 ? 0 : plane), bt;
+
+ int G = 0, index;
+ bool brk = false;
+ unsigned char S1;
+
+ for(int f = 0;f < h;f++)
+ {
+ for(int i = 0, g = 0;;g++)
+ {
+ bt = *(d + G);
+ G++;
+
+ for(int F = 256;F >= 2;F /= 2)
+ {
+ S1 = (unsigned char)(F / 2);
+ index = (bt&S1) ? 0 : 255;
+
+ fwrite(&index, 1, 1, fout);
+ fwrite(&index, 1, 1, fout);
+ fwrite(&index, 1, 1, fout);
+
+ if(++i >= w)
+ {
+ brk = true;
+ break;
+ }
+ }
+
+ if(brk)
+ {
+ brk = false;
+ break;
+ }
+ }
+ }
+ } else {
+ /* write PGM output file */
+ if ((size_t) jbg_dec_getplanes(&s) > sizeof(unsigned long) * 8)
+ {
+ fprintf(stderr, "Image has too many planes (%d)!\n", jbg_dec_getplanes(&s));
+ fclose(fout);
+ jbg_dec_free(&s);
+ return 1;
+ }
+ max = 0;
+ for (i = jbg_dec_getplanes(&s); i > 0; i--)
+ max = (max << 1) | 1;
+
+ int w, h, bpp = 24;
+
+ w = jbg_dec_getwidth(&s);
+ h = jbg_dec_getheight(&s);
+
+ fwrite(&w, sizeof(int), 1, fout);
+ fwrite(&h, sizeof(int), 1, fout);
+ fwrite(&bpp, sizeof(int), 1, fout);
+
+ koeff = 255.0 / max;
+
+ jbg_dec_merge_planes(&s, use_graycode, write_it, fout);
+ }
+
+ /* check for file errors and close fout */
+ if (ferror(fout) || fclose(fout)) {
+ fprintf(stderr, "Problem while writing output file '%s", fnout);
+ perror("'");
+ jbg_dec_free(&s);
+ return 1;
+ }
+
+ jbg_dec_free(&s);
+
+ return 0;
+}
diff --git a/kernel/kls_jbig/jbig2mem.h b/kernel/kls_jbig/jbig2mem.h
new file mode 100644
index 0000000..36ae619
--- /dev/null
+++ b/kernel/kls_jbig/jbig2mem.h
@@ -0,0 +1,6 @@
+#ifndef JBIG2MEM_H
+#define JBIG2MEM_H
+
+int jbig2mem(char *argv[]);
+
+#endif
diff --git a/kernel/kls_jbig/libjbig/ANNOUNCE b/kernel/kls_jbig/libjbig/ANNOUNCE
new file mode 100644
index 0000000..35baa23
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/ANNOUNCE
@@ -0,0 +1,147 @@
+
+JBIG-KIT lossless image compression library
+-------------------------------------------
+
+by Markus Kuhn
+
+
+The latest release of JBIG-KIT can be downloaded from
+
+ http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+
+JBIG-KIT implements a highly effective data compression algorithm for
+bi-level high-resolution images such as fax pages or scanned
+documents.
+
+JBIG-KIT provides a portable library of compression and decompression
+functions with a documented interface. You can very easily include
+into your image or document processing software. In addition, JBIG-KIT
+provides ready-to-use compression and decompression programs with a
+simple command line interface (similar to the converters found in Jef
+Poskanzer's PBM graphics file conversion package).
+
+JBIG-KIT implements the specification
+
+ International Standard ISO/IEC 11544:1993 and ITU-T Recommendation
+ T.82(1993), "Information technology - Coded representation of picture
+ and audio information - progressive bi-level image compression",
+ <http://www.itu.int/rec/recommendation.asp?type=folders&parent=T-REC-T.82>,
+
+which is commonly referred to as the "JBIG1 standard". JBIG (Joint
+Bi-level Image experts Group) is the committee which developed this
+international standard for the lossless compression of images using
+arithmetic coding. Like the well-known compression algorithms JPEG and
+MPEG, JBIG has also been developed and published by the International
+Organization for Standardization (ISO) and the International
+Telecommunication Union (ITU). See also
+
+ http://www.jbig.org/jbighomepage.html
+ http://www.iso.ch/
+ http://www.itu.int/
+
+The JBIG compression algorithm offers the following features:
+
+ - Close to state-of-the-art lossless compression ratio for high
+ resolution bi-level images.
+
+ - About 1.1 to 1.5 times better compression ratio on typical
+ scanned documents compared to G4 fax compression (ITU-T T.6),
+ which has been the best compression algorithm for scanned
+ documents available prior to JBIG.
+
+ - Up to 30 times better compression of scanned images with dithered
+ images compared to G4 fax compression.
+
+ - About 2 times better compression on typical 300 dpi documents
+ compared to 'gzip -9' on raw bitmaps.
+
+ - About 3-4 times better compression than GIF on typical 300 dpi
+ documents.
+
+ - Even much better competitive compression results on computer
+ generated images which are free of scanning distortions.
+
+ - JBIG supports hierarchical "progressive" encoding, that means it is
+ possible to encode a low resolution image first, followed by
+ resolution enhancement data. This allows, for instance, a document
+ browser to display already a good 75 dpi low resolution version of
+ an image, while the data necessary to reconstruct the full 300 dpi
+ version for laser printer reproduction is still arriving (say
+ over a slow network link or mass storage medium).
+
+ - The various resolution layers of a JBIG image in progressive
+ encoding mode together require not much more space than a
+ normal non-progressive mode encoded image (which JBIG also
+ supports).
+
+ - The progressive encoding mode utilizes a quite sophisticated
+ resolution reduction algorithm which offers high quality low
+ resolution versions that preserve the shape of characters as well
+ as the integrity of thin lines and dithered images.
+
+ - JBIG supports multiple bit planes and can this way also be used
+ for grayscale and color images, although the main field of
+ application is compression of bi-level images, i.e. images with
+ only two different pixel values. For grayscale images with up to
+ 6 bit per pixel, JBIG performs superior to JPEG's lossless
+ mode.
+
+JBIG-KIT is free software under the GNU General Public License. Other
+license arrangements suitable for commercial applications are
+available as well, please contact the author for details. JBIG-KIT
+provides a portable library implemented in ANSI/ISO C for encoding and
+decoding JBIG data streams, along with documentation. The library is
+not intended for 8-bit or 16-bit machine architectures (e.g., old
+MS-DOS C compilers) on which a number of very efficient optimization
+techniques used in this software are not possible. For maximum
+performance, a 32-bit processor is required (64-bit systems work too,
+of course). On architectures with 16-bit pointer arithmetic, only very
+small images can be processed.
+
+Special features of the JBIG-KIT implementation are:
+
+ - Fully reentrant multithread-capable design (no global or static
+ variables, isolated malloc()/free() calls, etc.).
+
+ - Capable of handling incomplete and growing JBIG data streams in
+ order to allow earliest display of low resolution versions.
+
+ - Capable of handling several incoming data streams simultaneously
+ in one single process and thread.
+
+ - Especially designed with applications in mind that want to display
+ incoming data as early as possible (e.g., similar to the way in
+ which Netscape Navigator handles incoming GIF images).
+
+ - Implements all JBIG features and options including progressive and
+ sequential encoding, multiple bit planes, user specified
+ resolution reduction and deterministic prediction tables, adaptive
+ template changes for optimal performance on half-tone images,
+ deterministic prediction, typical prediction in lowest and
+ differential layers, various stripe orderings, etc. Only the SEQ
+ and HITOLO options are currently not supported by the decoder
+ (they are normally never required, but could be added later in
+ case of user requirements).
+
+ - Suitable for fax applications, satisfies ITU-T T.85 profile
+
+ - Efficient code, optimized utilization of 32-bit processor
+ registers.
+
+ - Very easy to use documented C library interface.
+
+ - Included Gray code conversion routines for efficient encoding
+ of grayscale images.
+
+ - Ready-to-use pbmtojbg and jbgtopbm converters.
+
+I will try to provide free support and maintenance for this software
+for the foreseeable future, depending on my available time.
+
+Happy compressing ...
+
+Markus Kuhn
+
+--
+Markus Kuhn, Computer Laboratory, University of Cambridge
+http://www.cl.cam.ac.uk/~mgk25/ || CB3 0FD, Great Britain
diff --git a/kernel/kls_jbig/libjbig/COPYING b/kernel/kls_jbig/libjbig/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/kernel/kls_jbig/libjbig/Makefile.am b/kernel/kls_jbig/libjbig/Makefile.am
new file mode 100644
index 0000000..4fd99b2
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/Makefile.am
@@ -0,0 +1,5 @@
+noinst_LTLIBRARIES = libjbig.la
+
+libjbig_la_SOURCES = jbig.c jbig.h jbig_tab.c
+
+EXTRA_DIST = COPYING ANNOUNCE \ No newline at end of file
diff --git a/kernel/kls_jbig/libjbig/jbig.c b/kernel/kls_jbig/libjbig/jbig.c
new file mode 100644
index 0000000..6d8afa3
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/jbig.c
@@ -0,0 +1,3190 @@
+/*
+ * Portable Free JBIG image compression library
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ * $Id: jbig.c,v 1.22 2004-06-11 15:17:06+01 mgk25 Exp $
+ *
+ * This module implements a portable standard C encoder and decoder
+ * using the JBIG lossless bi-level image compression algorithm as
+ * specified in International Standard ISO 11544:1993 or equivalently
+ * as specified in ITU-T Recommendation T.82. See the file jbig.doc
+ * for usage instructions and application examples.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * If you want to use this program under different license conditions,
+ * then contact the author for an arrangement.
+ *
+ * It is possible that certain products which can be built using this
+ * software module might form inventions protected by patent rights in
+ * some countries (e.g., by patents about arithmetic coding algorithms
+ * owned by IBM and AT&T in the USA). Provision of this software by the
+ * author does NOT include any licences for any patents. In those
+ * countries where a patent licence is required for certain applications
+ * of this software module, you will have to obtain such a licence
+ * yourself.
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#else
+#define NDEBUG
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "jbig.h"
+
+
+/* optional export of arithmetic coder functions for test purposes */
+#define ARITH static
+#ifdef __GNUC__
+#define ARITH_INL static __inline__
+#else
+#define ARITH_INL static
+#endif
+
+#define MX_MAX 127 /* maximal supported mx offset for
+ * adaptive template in the encoder */
+
+#define TPB2CX 0x195 /* contexts for TP special pixels */
+#define TPB3CX 0x0e5
+#define TPDCX 0xc3f
+
+/* marker codes */
+#define MARKER_STUFF 0x00
+#define MARKER_RESERVE 0x01
+#define MARKER_SDNORM 0x02
+#define MARKER_SDRST 0x03
+#define MARKER_ABORT 0x04
+#define MARKER_NEWLEN 0x05
+#define MARKER_ATMOVE 0x06
+#define MARKER_COMMENT 0x07
+#define MARKER_ESC 0xff
+
+/* loop array indices */
+#define STRIPE 0
+#define LAYER 1
+#define PLANE 2
+
+/* special jbg_buf pointers (instead of NULL) */
+#define SDE_DONE ((struct jbg_buf *) -1)
+#define SDE_TODO ((struct jbg_buf *) 0)
+
+/* object code version id */
+
+const char jbg_version[] =
+" JBIG-KIT " JBG_VERSION " -- Markus Kuhn -- "
+"$Id: jbig.c,v 1.22 2004-06-11 15:17:06+01 mgk25 Exp $ ";
+
+/*
+ * the following array specifies for each combination of the 3
+ * ordering bits, which ii[] variable represents which dimension
+ * of s->sde.
+ */
+static const int iindex[8][3] = {
+ { 2, 1, 0 }, /* no ordering bit set */
+ { -1, -1, -1}, /* SMID -> illegal combination */
+ { 2, 0, 1 }, /* ILEAVE */
+ { 1, 0, 2 }, /* SMID + ILEAVE */
+ { 0, 2, 1 }, /* SEQ */
+ { 1, 2, 0 }, /* SEQ + SMID */
+ { 0, 1, 2 }, /* SEQ + ILEAVE */
+ { -1, -1, -1 } /* SEQ + SMID + ILEAVE -> illegal combination */
+};
+
+unsigned char *jbg_next_pscdms(unsigned char *p, size_t len);
+
+
+/*
+ * Array [language][message] with text string error messages that correspond
+ * to return values from public functions in this library.
+ */
+#define NEMSG 9 /* number of error codes */
+#define NEMSG_LANG 3 /* number of supported languages */
+static const char *errmsg[NEMSG_LANG][NEMSG] = {
+ /* English (JBG_EN) */
+ {
+ "Everything is ok", /* JBG_EOK */
+ "Reached specified maximum size", /* JBG_EOK_INTR */
+ "Unexpected end of data", /* JBG_EAGAIN */
+ "Not enough memory available", /* JBG_ENOMEM */
+ "ABORT marker found", /* JBG_EABORT */
+ "Unknown marker segment encountered", /* JBG_EMARKER */
+ "Incremental BIE does not fit to previous one", /* JBG_ENOCONT */
+ "Invalid data encountered", /* JBG_EINVAL */
+ "Unimplemented features used" /* JBG_EIMPL */
+ },
+ /* German (JBG_DE_8859_1) */
+ {
+ "Kein Problem aufgetreten", /* JBG_EOK */
+ "Angegebene maximale Bildgr\366\337e erreicht", /* JBG_EOK_INTR */
+ "Unerwartetes Ende der Daten", /* JBG_EAGAIN */
+ "Nicht gen\374gend Speicher vorhanden", /* JBG_ENOMEM */
+ "Es wurde eine Abbruch-Sequenz gefunden", /* JBG_EABORT */
+ "Eine unbekannte Markierungssequenz wurde gefunden", /* JBG_EMARKER */
+ "Neue Daten passen nicht zu vorangegangenen Daten", /* JBG_ENOCONT */
+ "Es wurden ung\374ltige Daten gefunden", /* JBG_EINVAL */
+ "Noch nicht implementierte Optionen wurden benutzt" /* JBG_EIMPL */
+ },
+ /* German (JBG_DE_UTF_8) */
+ {
+ "Kein Problem aufgetreten", /* JBG_EOK */
+ "Angegebene maximale Bildgr\303\266\303\237e erreicht", /* JBG_EOK_INTR */
+ "Unerwartetes Ende der Daten", /* JBG_EAGAIN */
+ "Nicht gen\303\274gend Speicher vorhanden", /* JBG_ENOMEM */
+ "Es wurde eine Abbruch-Sequenz gefunden", /* JBG_EABORT */
+ "Eine unbekannte Markierungssequenz wurde gefunden", /* JBG_EMARKER */
+ "Neue Daten passen nicht zu vorangegangenen Daten", /* JBG_ENOCONT */
+ "Es wurden ung\303\274ltige Daten gefunden", /* JBG_EINVAL */
+ "Noch nicht implementierte Optionen wurden benutzt" /* JBG_EIMPL */
+ }
+};
+
+
+
+/*
+ * The following three functions are the only places in this code, were
+ * C library memory management functions are called. The whole JBIG
+ * library has been designed in order to allow multi-threaded
+ * execution. No static or global variables are used, so all fuctions
+ * are fully reentrant. However if you want to use this multi-thread
+ * capability and your malloc, realloc and free are not reentrant,
+ * then simply add the necessary semaphores or mutex primitives below.
+ * In contrast to C's malloc() and realloc(), but like C's calloc(),
+ * these functions take two parameters nmemb and size that are multiplied
+ * before being passed on to the corresponding C function.
+ * This we can catch all overflows during a size_t multiplication a
+ * a single place.
+ */
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1) /* largest value of size_t */
+#endif
+
+static void *checked_malloc(size_t nmemb, size_t size)
+{
+ void *p;
+
+ /* Full manual exception handling is ugly here for performance
+ * reasons. If an adequate handling of lack of memory is required,
+ * then use C++ and throw a C++ exception instead of abort(). */
+
+ /* assert that nmemb * size <= SIZE_MAX */
+ if (size > SIZE_MAX / nmemb)
+ abort();
+
+ p = malloc(nmemb * size);
+
+ if (!p)
+ abort();
+
+#if 0
+ fprintf(stderr, "%p = malloc(%lu * %lu)\n", p,
+ (unsigned long) nmemb, (unsigned long) size);
+#endif
+
+ return p;
+}
+
+
+static void *checked_realloc(void *ptr, size_t nmemb, size_t size)
+{
+ void *p;
+
+ /* Full manual exception handling is ugly here for performance
+ * reasons. If an adequate handling of lack of memory is required,
+ * then use C++ and throw a C++ exception here instead of abort(). */
+
+ /* assert that nmemb * size <= SIZE_MAX */
+ if (size > SIZE_MAX / nmemb)
+ abort();
+
+ p = realloc(ptr, nmemb * size);
+
+ if (!p)
+ abort();
+
+#if 0
+ fprintf(stderr, "%p = realloc(%p, %lu * %lu)\n", p, ptr,
+ (unsigned long) nmemb, (unsigned long) size);
+#endif
+
+ return p;
+}
+
+
+static void checked_free(void *ptr)
+{
+ free(ptr);
+
+#if 0
+ fprintf(stderr, "free(%p)\n", ptr);
+#endif
+
+}
+
+
+
+/*
+ * The next functions implement the arithmedic encoder and decoder
+ * required for JBIG. The same algorithm is also used in the arithmetic
+ * variant of JPEG.
+ */
+
+#ifdef DEBUG
+static long encoded_pixels = 0;
+#endif
+
+ARITH void arith_encode_init(struct jbg_arenc_state *s, int reuse_st)
+{
+ int i;
+
+ if (!reuse_st)
+ for (i = 0; i < 4096; s->st[i++] = 0);
+ s->c = 0;
+ s->a = 0x10000L;
+ s->sc = 0;
+ s->ct = 11;
+ s->buffer = -1; /* empty */
+
+ return;
+}
+
+
+ARITH void arith_encode_flush(struct jbg_arenc_state *s)
+{
+ unsigned long temp;
+
+#ifdef DEBUG
+ fprintf(stderr, " encoded pixels = %ld, a = %05lx, c = %08lx\n",
+ encoded_pixels, s->a, s->c);
+#endif
+
+ /* find the s->c in the coding interval with the largest
+ * number of trailing zero bits */
+ if ((temp = (s->a - 1 + s->c) & 0xffff0000L) < s->c)
+ s->c = temp + 0x8000;
+ else
+ s->c = temp;
+ /* send remaining bytes to output */
+ s->c <<= s->ct;
+ if (s->c & 0xf8000000L) {
+ /* one final overflow has to be handled */
+ if (s->buffer >= 0) {
+ s->byte_out(s->buffer + 1, s->file);
+ if (s->buffer + 1 == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ /* output 0x00 bytes only when more non-0x00 will follow */
+ if (s->c & 0x7fff800L)
+ for (; s->sc; --s->sc)
+ s->byte_out(0x00, s->file);
+ } else {
+ if (s->buffer >= 0)
+ s->byte_out(s->buffer, s->file);
+ /* T.82 figure 30 says buffer+1 for the above line! Typo? */
+ for (; s->sc; --s->sc) {
+ s->byte_out(0xff, s->file);
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ }
+ /* output final bytes only if they are not 0x00 */
+ if (s->c & 0x7fff800L) {
+ s->byte_out((s->c >> 19) & 0xff, s->file);
+ if (((s->c >> 19) & 0xff) == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ if (s->c & 0x7f800L) {
+ s->byte_out((s->c >> 11) & 0xff, s->file);
+ if (((s->c >> 11) & 0xff) == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ }
+
+ return;
+}
+
+
+ARITH_INL void arith_encode(struct jbg_arenc_state *s, int cx, int pix)
+{
+ extern short jbg_lsz[];
+ extern unsigned char jbg_nmps[], jbg_nlps[];
+ register unsigned lsz, ss;
+ register unsigned char *st;
+ long temp;
+
+#ifdef DEBUG
+ ++encoded_pixels;
+#endif
+
+ assert(cx >= 0 && cx < 4096);
+ st = s->st + cx;
+ ss = *st & 0x7f;
+ assert(ss < 113);
+ lsz = jbg_lsz[ss];
+
+#if 0
+ fprintf(stderr, "pix = %d, cx = %d, mps = %d, st = %3d, lsz = 0x%04x, "
+ "a = 0x%05lx, c = 0x%08lx, ct = %2d, buf = 0x%02x\n",
+ pix, cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct,
+ s->buffer);
+#endif
+
+ if (((pix << 7) ^ s->st[cx]) & 0x80) {
+ /* encode the less probable symbol */
+ if ((s->a -= lsz) >= lsz) {
+ /* If the interval size (lsz) for the less probable symbol (LPS)
+ * is larger than the interval size for the MPS, then exchange
+ * the two symbols for coding efficiency, otherwise code the LPS
+ * as usual: */
+ s->c += s->a;
+ s->a = lsz;
+ }
+ /* Check whether MPS/LPS exchange is necessary
+ * and chose next probability estimator status */
+ *st &= 0x80;
+ *st ^= jbg_nlps[ss];
+ } else {
+ /* encode the more probable symbol */
+ if ((s->a -= lsz) & 0xffff8000L)
+ return; /* A >= 0x8000 -> ready, no renormalization required */
+ if (s->a < lsz) {
+ /* If the interval size (lsz) for the less probable symbol (LPS)
+ * is larger than the interval size for the MPS, then exchange
+ * the two symbols for coding efficiency: */
+ s->c += s->a;
+ s->a = lsz;
+ }
+ /* chose next probability estimator status */
+ *st &= 0x80;
+ *st |= jbg_nmps[ss];
+ }
+
+ /* renormalization of coding interval */
+ do {
+ s->a <<= 1;
+ s->c <<= 1;
+ --s->ct;
+ if (s->ct == 0) {
+ /* another byte is ready for output */
+ temp = s->c >> 19;
+ if (temp & 0xffffff00L) {
+ /* handle overflow over all buffered 0xff bytes */
+ if (s->buffer >= 0) {
+ ++s->buffer;
+ s->byte_out(s->buffer, s->file);
+ if (s->buffer == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ for (; s->sc; --s->sc)
+ s->byte_out(0x00, s->file);
+ s->buffer = temp & 0xff; /* new output byte, might overflow later */
+ assert(s->buffer != 0xff);
+ /* can s->buffer really never become 0xff here? */
+ } else if (temp == 0xff) {
+ /* buffer 0xff byte (which might overflow later) */
+ ++s->sc;
+ } else {
+ /* output all buffered 0xff bytes, they will not overflow any more */
+ if (s->buffer >= 0)
+ s->byte_out(s->buffer, s->file);
+ for (; s->sc; --s->sc) {
+ s->byte_out(0xff, s->file);
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ s->buffer = temp; /* buffer new output byte (can still overflow) */
+ }
+ s->c &= 0x7ffffL;
+ s->ct = 8;
+ }
+ } while (s->a < 0x8000);
+
+ return;
+}
+
+
+ARITH void arith_decode_init(struct jbg_ardec_state *s, int reuse_st)
+{
+ int i;
+
+ if (!reuse_st)
+ for (i = 0; i < 4096; s->st[i++] = 0);
+ s->c = 0;
+ s->a = 1;
+ s->ct = 0;
+ s->result = JBG_OK;
+ s->startup = 1;
+ return;
+}
+
+
+ARITH_INL int arith_decode(struct jbg_ardec_state *s, int cx)
+{
+ extern short jbg_lsz[];
+ extern unsigned char jbg_nmps[], jbg_nlps[];
+ register unsigned lsz, ss;
+ register unsigned char *st;
+ int pix;
+
+ /* renormalization */
+ while (s->a < 0x8000 || s->startup) {
+ if (s->ct < 1 && s->result != JBG_READY) {
+ /* first we have to move a new byte into s->c */
+ if (s->pscd_ptr >= s->pscd_end) {
+ s->result = JBG_MORE;
+ return -1;
+ }
+ if (*s->pscd_ptr == 0xff)
+ if (s->pscd_ptr + 1 >= s->pscd_end) {
+ s->result = JBG_MARKER;
+ return -1;
+ } else {
+ if (*(s->pscd_ptr + 1) == MARKER_STUFF) {
+ s->c |= 0xffL << (8 - s->ct);
+ s->ct += 8;
+ s->pscd_ptr += 2;
+ s->result = JBG_OK;
+ } else
+ s->result = JBG_READY;
+ }
+ else {
+ s->c |= (long)*(s->pscd_ptr++) << (8 - s->ct);
+ s->ct += 8;
+ s->result = JBG_OK;
+ }
+ }
+ s->c <<= 1;
+ s->a <<= 1;
+ --s->ct;
+ if (s->a == 0x10000L)
+ s->startup = 0;
+ }
+
+ st = s->st + cx;
+ ss = *st & 0x7f;
+ assert(ss < 113);
+ lsz = jbg_lsz[ss];
+
+#if 0
+ fprintf(stderr, "cx = %d, mps = %d, st = %3d, lsz = 0x%04x, a = 0x%05lx, "
+ "c = 0x%08lx, ct = %2d\n",
+ cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct);
+#endif
+
+ if ((s->c >> 16) < (s->a -= lsz))
+ if (s->a & 0xffff8000L)
+ return *st >> 7;
+ else {
+ /* MPS_EXCHANGE */
+ if (s->a < lsz) {
+ pix = 1 - (*st >> 7);
+ /* Check whether MPS/LPS exchange is necessary
+ * and chose next probability estimator status */
+ *st &= 0x80;
+ *st ^= jbg_nlps[ss];
+ } else {
+ pix = *st >> 7;
+ *st &= 0x80;
+ *st |= jbg_nmps[ss];
+ }
+ }
+ else {
+ /* LPS_EXCHANGE */
+ if (s->a < lsz) {
+ s->c -= s->a << 16;
+ s->a = lsz;
+ pix = *st >> 7;
+ *st &= 0x80;
+ *st |= jbg_nmps[ss];
+ } else {
+ s->c -= s->a << 16;
+ s->a = lsz;
+ pix = 1 - (*st >> 7);
+ /* Check whether MPS/LPS exchange is necessary
+ * and chose next probability estimator status */
+ *st &= 0x80;
+ *st ^= jbg_nlps[ss];
+ }
+ }
+
+ return pix;
+}
+
+
+
+/*
+ * Memory management for buffers which are used for temporarily
+ * storing SDEs by the encoder.
+ *
+ * The following functions manage a set of struct jbg_buf storage
+ * containers were each can keep JBG_BUFSIZE bytes. The jbg_buf
+ * containers can be linked to form linear double-chained lists for
+ * which a number of operations are provided. Blocks which are
+ * tempoarily not used any more are returned to a freelist which each
+ * encoder keeps. Only the destructor of the encoder actually returns
+ * the block via checked_free() to the stdlib memory management.
+ */
+
+
+/*
+ * Allocate a new buffer block and initialize it. Try to get it from
+ * the free_list, and if it is empty, call checked_malloc().
+ */
+static struct jbg_buf *jbg_buf_init(struct jbg_buf **free_list)
+{
+ struct jbg_buf *new_block;
+
+ /* Test whether a block from the free list is available */
+ if (*free_list) {
+ new_block = *free_list;
+ *free_list = new_block->next;
+ } else {
+ /* request a new memory block */
+ new_block = (struct jbg_buf *) checked_malloc(1, sizeof(struct jbg_buf));
+ }
+ new_block->len = 0;
+ new_block->next = NULL;
+ new_block->previous = NULL;
+ new_block->last = new_block;
+ new_block->free_list = free_list;
+
+ return new_block;
+}
+
+
+/*
+ * Return an entire free_list to the memory management of stdlib.
+ * This is only done by jbg_enc_free().
+ */
+static void jbg_buf_free(struct jbg_buf **free_list)
+{
+ struct jbg_buf *tmp;
+
+ while (*free_list) {
+ tmp = (*free_list)->next;
+ checked_free(*free_list);
+ *free_list = tmp;
+ }
+
+ return;
+}
+
+
+/*
+ * Append a single byte to a single list that starts with the block
+ * *(struct jbg_buf *) head. The type of *head is void here in order to
+ * keep the interface of the arithmetic encoder gereric, which uses this
+ * function as a call-back function in order to deliver single bytes
+ * for a PSCD.
+ */
+static void jbg_buf_write(int b, void *head)
+{
+ struct jbg_buf *now;
+
+ now = ((struct jbg_buf *) head)->last;
+ if (now->len < JBG_BUFSIZE - 1) {
+ now->d[now->len++] = b;
+ return;
+ }
+ now->next = jbg_buf_init(((struct jbg_buf *) head)->free_list);
+ now->next->previous = now;
+ now->next->d[now->next->len++] = b;
+ ((struct jbg_buf *) head)->last = now->next;
+
+ return;
+}
+
+
+/*
+ * Remove any trailing zero bytes from the end of a linked jbg_buf list,
+ * however make sure that no zero byte is removed which directly
+ * follows a 0xff byte (i.e., keep MARKER_ESC MARKER_STUFF sequences
+ * intact). This function is used to remove any redundant final zero
+ * bytes from a PSCD.
+ */
+static void jbg_buf_remove_zeros(struct jbg_buf *head)
+{
+ struct jbg_buf *last;
+
+ while (1) {
+ /* remove trailing 0x00 in last block of list until this block is empty */
+ last = head->last;
+ while (last->len && last->d[last->len - 1] == 0)
+ last->len--;
+ /* if block became really empty, remove it in case it is not the
+ * only remaining block and then loop to next block */
+ if (last->previous && !last->len) {
+ head->last->next = *head->free_list;
+ *head->free_list = head->last;
+ head->last = last->previous;
+ head->last->next = NULL;
+ } else
+ break;
+ }
+
+ /*
+ * If the final non-zero byte is 0xff (MARKER_ESC), then we just have
+ * removed a MARKER_STUFF and we will append it again now in order
+ * to preserve PSCD status of byte stream.
+ */
+ if (head->last->len && head->last->d[head->last->len - 1] == MARKER_ESC)
+ jbg_buf_write(MARKER_STUFF, head);
+
+ return;
+}
+
+
+/*
+ * The jbg_buf list which starts with block *new_prefix is concatenated
+ * with the list which starts with block **start and *start will then point
+ * to the first block of the new list.
+ */
+static void jbg_buf_prefix(struct jbg_buf *new_prefix, struct jbg_buf **start)
+{
+ new_prefix->last->next = *start;
+ new_prefix->last->next->previous = new_prefix->last;
+ new_prefix->last = new_prefix->last->next->last;
+ *start = new_prefix;
+
+ return;
+}
+
+
+/*
+ * Send the contents of a jbg_buf list that starts with block **head to
+ * the call back function data_out and return the blocks of the jbg_buf
+ * list to the freelist from which these jbg_buf blocks have been taken.
+ * After the call, *head == NULL.
+ */
+static void jbg_buf_output(struct jbg_buf **head,
+ void (*data_out)(unsigned char *start,
+ size_t len, void *file),
+ void *file)
+{
+ struct jbg_buf *tmp;
+
+ while (*head) {
+ data_out((*head)->d, (*head)->len, file);
+ tmp = (*head)->next;
+ (*head)->next = *(*head)->free_list;
+ *(*head)->free_list = *head;
+ *head = tmp;
+ }
+
+ return;
+}
+
+
+/*
+ * Calculate y = ceil(x/2) applied n times, which is equivalent to
+ * y = ceil(x/(2^n)). This function is used to
+ * determine the number of pixels per row or column after n resolution
+ * reductions. E.g. X[d-1] = jbg_ceil_half(X[d], 1) and X[0] =
+ * jbg_ceil_half(X[d], d) as defined in clause 6.2.3 of T.82.
+ */
+unsigned long jbg_ceil_half(unsigned long x, int n)
+{
+ unsigned long mask;
+
+ assert(n >= 0 && n < 32);
+ mask = (1UL << n) - 1; /* the lowest n bits are 1 here */
+ return (x >> n) + ((mask & x) != 0);
+}
+
+
+/*
+ * Set L0 (the number of lines in a stripe at lowest resolution)
+ * to a default value, such that there are about 35 stripes, as
+ * suggested in Annex C of ITU-T T.82, without exceeding the
+ * limit 128/2^D suggested in Annex A.
+ */
+static void jbg_set_default_l0(struct jbg_enc_state *s)
+{
+ s->l0 = jbg_ceil_half(s->yd, s->d) / 35; /* 35 stripes/image */
+ while ((s->l0 << s->d) > 128) /* but <= 128 lines/stripe */
+ --s->l0;
+ if (s->l0 < 2) s->l0 = 2;
+}
+
+
+/*
+ * Calculate the number of stripes, as defined in clause 6.2.3 of T.82.
+ */
+static unsigned long jbg_stripes(unsigned long l0, unsigned long yd,
+ unsigned long d)
+{
+ unsigned long y0 = jbg_ceil_half(yd, d);
+
+ return y0 / l0 + (y0 % l0 != 0);
+}
+
+
+/*
+ * Initialize the status struct for the encoder.
+ */
+void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+ int planes, unsigned char **p,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file)
+{
+ unsigned long l, lx;
+ int i;
+
+ extern char jbg_resred[], jbg_dptable[];
+
+ s->xd = x;
+ s->yd = y;
+ s->yd1 = y; /* This is the hight initially announced in BIH. To provoke
+ generation of NEWLEN for T.85 compatibility tests,
+ overwrite with new value s->yd1 > s->yd */
+ s->planes = planes;
+ s->data_out = data_out;
+ s->file = file;
+
+ s->d = 0;
+ s->dl = 0;
+ s->dh = s->d;
+ jbg_set_default_l0(s);
+ s->mx = 8;
+ s->my = 0;
+ s->order = JBG_ILEAVE | JBG_SMID;
+ s->options = JBG_TPBON | JBG_TPDON | JBG_DPON;
+ s->dppriv = jbg_dptable;
+ s->res_tab = jbg_resred;
+
+ s->highres = (int *) checked_malloc(planes, sizeof(int));
+ s->lhp[0] = p;
+ s->lhp[1] = (unsigned char **)
+ checked_malloc(planes, sizeof(unsigned char *));
+ for (i = 0; i < planes; i++) {
+ s->highres[i] = 0;
+ s->lhp[1][i] = (unsigned char *)
+ checked_malloc(jbg_ceil_half(y, 1), jbg_ceil_half(x, 1+3));
+ }
+
+ s->free_list = NULL;
+ s->s = (struct jbg_arenc_state *)
+ checked_malloc(s->planes, sizeof(struct jbg_arenc_state));
+ s->tx = (int *) checked_malloc(s->planes, sizeof(int));
+ lx = jbg_ceil_half(x, 1);
+ s->tp = (char *) checked_malloc(lx, sizeof(char));
+ for (l = 0; l < lx; s->tp[l++] = 2);
+ s->sde = NULL;
+
+ return;
+}
+
+
+/*
+ * This function selects the number of differential layers based on
+ * the maximum size requested for the lowest resolution layer. If
+ * possible, a number of differential layers is selected, which will
+ * keep the size of the lowest resolution layer below or equal to the
+ * given width x and height y. However not more than 6 differential
+ * resolution layers will be used. In addition, a reasonable value for
+ * l0 (height of one stripe in the lowest resolution layer) is
+ * selected, which obeys the recommended limitations for l0 in annex A
+ * and C of the JBIG standard. The selected number of resolution layers
+ * is returned.
+ */
+int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long x,
+ unsigned long y)
+{
+ for (s->d = 0; s->d < 6; s->d++)
+ if (jbg_ceil_half(s->xd, s->d) <= x && jbg_ceil_half(s->yd, s->d) <= y)
+ break;
+ s->dl = 0;
+ s->dh = s->d;
+ jbg_set_default_l0(s);
+ return s->d;
+}
+
+
+/*
+ * As an alternative to jbg_enc_lrlmax(), the following function allows
+ * to specify the number of layers directly. The stripe height and layer
+ * range is also adjusted automatically here.
+ */
+void jbg_enc_layers(struct jbg_enc_state *s, int d)
+{
+ if (d < 0 || d > 31)
+ return;
+ s->d = d;
+ s->dl = 0;
+ s->dh = s->d;
+ jbg_set_default_l0(s);
+ return;
+}
+
+
+/*
+ * Specify the highest and lowest resolution layers which will be
+ * written to the output file. Call this function not before
+ * jbg_enc_layers() or jbg_enc_lrlmax(), because these two functions
+ * reset the lowest and highest resolution layer to default values.
+ * Negative values are ignored. The total number of layers is returned.
+ */
+int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh)
+{
+ if (dl >= 0 && dl <= s->d) s->dl = dl;
+ if (dh >= s->dl && dh <= s->d) s->dh = dh;
+
+ return s->d;
+}
+
+
+/*
+ * The following function allows to specify the bits describing the
+ * options of the format as well as the maximum AT movement window and
+ * the number of layer 0 lines per stripes.
+ */
+void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+ unsigned long l0, int mx, int my)
+{
+ if (order >= 0 && order <= 0x0f) s->order = order;
+ if (options >= 0) s->options = options;
+ if (l0 > 0) s->l0 = l0;
+ if (mx >= 0 && my < 128) s->mx = mx;
+ if (my >= 0 && my < 256) s->my = my;
+
+ return;
+}
+
+
+/*
+ * This function actually does all the tricky work involved in producing
+ * a SDE, which is stored in the appropriate s->sde[][][] element
+ * for later output in the correct order.
+ */
+static void encode_sde(struct jbg_enc_state *s,
+ long stripe, int layer, int plane)
+{
+ unsigned char *hp, *lp1, *lp2, *p0, *p1, *q1, *q2;
+ unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl;
+ unsigned long line_h0 = 0, line_h1 = 0;
+ unsigned long line_h2, line_h3, line_l1, line_l2, line_l3;
+ struct jbg_arenc_state *se;
+ unsigned long i, j, y;
+ long o;
+ unsigned a, p, t;
+ int ltp, ltp_old, cx;
+ unsigned long c_all, c[MX_MAX + 1], cmin, cmax, clmin, clmax;
+ int tmax, at_determined;
+ int new_tx;
+ long new_tx_line = -1;
+ struct jbg_buf *new_jbg_buf;
+
+#ifdef DEBUG
+ static long tp_lines, tp_exceptions, tp_pixels, dp_pixels;
+ static long encoded_pixels;
+#endif
+
+ /* return immediately if this stripe has already been encoded */
+ if (s->sde[stripe][layer][plane] != SDE_TODO)
+ return;
+
+#ifdef DEBUG
+ if (stripe == 0)
+ tp_lines = tp_exceptions = tp_pixels = dp_pixels = encoded_pixels = 0;
+ fprintf(stderr, "encode_sde: s/d/p = %2ld/%2d/%2d\n",
+ stripe, layer, plane);
+#endif
+
+ /* number of lines per stripe in highres image */
+ hl = s->l0 << layer;
+ /* number of lines per stripe in lowres image */
+ ll = hl >> 1;
+ /* current line number in highres image */
+ y = stripe * hl;
+ /* number of pixels in highres image */
+ hx = jbg_ceil_half(s->xd, s->d - layer);
+ hy = jbg_ceil_half(s->yd, s->d - layer);
+ /* number of pixels in lowres image */
+ lx = jbg_ceil_half(hx, 1);
+ ly = jbg_ceil_half(hy, 1);
+ /* bytes per line in highres and lowres image */
+ hbpl = jbg_ceil_half(hx, 3);
+ lbpl = jbg_ceil_half(lx, 3);
+ /* pointer to first image byte of highres stripe */
+ hp = s->lhp[s->highres[plane]][plane] + stripe * hl * hbpl;
+ lp2 = s->lhp[1 - s->highres[plane]][plane] + stripe * ll * lbpl;
+ lp1 = lp2 + lbpl;
+
+ /* initialize arithmetic encoder */
+ se = s->s + plane;
+ arith_encode_init(se, stripe != 0);
+ s->sde[stripe][layer][plane] = jbg_buf_init(&s->free_list);
+ se->byte_out = jbg_buf_write;
+ se->file = s->sde[stripe][layer][plane];
+
+ /* initialize adaptive template movement algorithm */
+ c_all = 0;
+ for (t = 0; t <= s->mx; t++)
+ c[t] = 0;
+ if (stripe == 0)
+ s->tx[plane] = 0;
+ new_tx = -1;
+ at_determined = 0; /* we haven't yet decided the template move */
+ if (s->mx == 0)
+ at_determined = 1;
+
+ /* initialize typical prediction */
+ ltp = 0;
+ if (stripe == 0)
+ ltp_old = 0;
+ else {
+ ltp_old = 1;
+ p1 = hp - hbpl;
+ if (y > 1) {
+ q1 = p1 - hbpl;
+ while (p1 < hp && (ltp_old = (*p1++ == *q1++)) != 0);
+ } else
+ while (p1 < hp && (ltp_old = (*p1++ == 0)) != 0);
+ }
+
+ if (layer == 0) {
+
+ /*
+ * Encode lowest resolution layer
+ */
+
+ for (i = 0; i < hl && y < hy; i++, y++) {
+
+ /* check whether it is worth to perform an ATMOVE */
+ if (!at_determined && c_all > 2048) {
+ cmin = clmin = 0xffffffffL;
+ cmax = clmax = 0;
+ tmax = 0;
+ for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) {
+ if (c[t] > cmax) cmax = c[t];
+ if (c[t] < cmin) cmin = c[t];
+ if (c[t] > c[tmax]) tmax = t;
+ }
+ clmin = (c[0] < cmin) ? c[0] : cmin;
+ clmax = (c[0] > cmax) ? c[0] : cmax;
+ if (c_all - cmax < (c_all >> 3) &&
+ cmax - c[s->tx[plane]] > c_all - cmax &&
+ cmax - c[s->tx[plane]] > (c_all >> 4) &&
+ /* ^ T.82 said < here, fixed in Cor.1/25 */
+ cmax - (c_all - c[s->tx[plane]]) > c_all - cmax &&
+ cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) &&
+ cmax - cmin > (c_all >> 2) &&
+ (s->tx[plane] || clmax - clmin > (c_all >> 3))) {
+ /* we have decided to perform an ATMOVE */
+ new_tx = tmax;
+ if (!(s->options & JBG_DELAY_AT)) {
+ new_tx_line = i;
+ s->tx[plane] = new_tx;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n",
+ i, new_tx, c_all);
+#endif
+ }
+ at_determined = 1;
+ }
+ assert(s->tx[plane] >= 0); /* i.e., tx can safely be cast to unsigned */
+
+ /* typical prediction */
+ if (s->options & JBG_TPBON) {
+ ltp = 1;
+ p1 = hp;
+ if (y > 0) {
+ q1 = hp - hbpl;
+ while (q1 < hp && (ltp = (*p1++ == *q1++)) != 0);
+ } else
+ while (p1 < hp + hbpl && (ltp = (*p1++ == 0)) != 0);
+ arith_encode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX,
+ ltp == ltp_old);
+#ifdef DEBUG
+ tp_lines += ltp;
+#endif
+ ltp_old = ltp;
+ if (ltp) {
+ /* skip next line */
+ hp += hbpl;
+ continue;
+ }
+ }
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the neighbour pixels of the currently coded pixel X:
+ *
+ * 76543210765432107654321076543210 line_h3
+ * 76543210765432107654321076543210 line_h2
+ * 76543210765432107654321X76543210 line_h1
+ */
+
+ line_h1 = line_h2 = line_h3 = 0;
+ if (y > 0) line_h2 = (long)*(hp - hbpl) << 8;
+ if (y > 1) line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+
+ /* encode line */
+ for (j = 0; j < hx; hp++) {
+ line_h1 |= *hp;
+ if (j < hbpl * 8 - 8 && y > 0) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (y > 1)
+ line_h3 |= *(hp - hbpl - hbpl + 1);
+ }
+ if (s->options & JBG_LRLTWO) {
+ /* two line template */
+ do {
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+ if (s->tx[plane]) {
+ if ((unsigned) s->tx[plane] > j)
+ a = 0;
+ else {
+ o = (j - s->tx[plane]) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(s->tx[plane] > 23 ||
+ a == ((line_h1 >> (4 + s->tx[plane])) & 0x010));
+ arith_encode(se, (((line_h2 >> 10) & 0x3e0) | a |
+ ((line_h1 >> 9) & 0x00f)),
+ (line_h1 >> 8) & 1);
+ }
+ else
+ arith_encode(se, (((line_h2 >> 10) & 0x3f0) |
+ ((line_h1 >> 9) & 0x00f)),
+ (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+ /* statistics for adaptive template changes */
+ if (!at_determined && j >= s->mx && j < hx-2) {
+ p = (line_h1 & 0x100) != 0; /* current pixel value */
+ c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+ assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+ (((line_h2 & 0x4000) != 0) == p));
+ for (t = 5; t <= s->mx && t <= j; t++) {
+ o = (j - t) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ assert(t > 23 ||
+ (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+ c[t] += a == p;
+ }
+ for (; t <= s->mx; t++) {
+ c[t] += 0 == p;
+ }
+ ++c_all;
+ }
+ } while (++j & 7 && j < hx);
+ } else {
+ /* three line template */
+ do {
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+ if (s->tx[plane]) {
+ if ((unsigned) s->tx[plane] > j)
+ a = 0;
+ else {
+ o = (j - s->tx[plane]) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 2;
+ }
+ assert(s->tx[plane] > 23 ||
+ a == ((line_h1 >> (6 + s->tx[plane])) & 0x004));
+ arith_encode(se, (((line_h3 >> 8) & 0x380) |
+ ((line_h2 >> 12) & 0x078) | a |
+ ((line_h1 >> 9) & 0x003)),
+ (line_h1 >> 8) & 1);
+ } else
+ arith_encode(se, (((line_h3 >> 8) & 0x380) |
+ ((line_h2 >> 12) & 0x07c) |
+ ((line_h1 >> 9) & 0x003)),
+ (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+ /* statistics for adaptive template changes */
+ if (!at_determined && j >= s->mx && j < hx-2) {
+ p = (line_h1 & 0x100) != 0; /* current pixel value */
+ c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+ assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+ (((line_h2 & 0x4000) != 0) == p));
+ for (t = 3; t <= s->mx && t <= j; t++) {
+ o = (j - t) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ assert(t > 23 ||
+ (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+ c[t] += a == p;
+ }
+ for (; t <= s->mx; t++) {
+ c[t] += 0 == p;
+ }
+ ++c_all;
+ }
+ } while (++j & 7 && j < hx);
+ } /* if (s->options & JBG_LRLTWO) */
+ } /* for (j = ...) */
+ } /* for (i = ...) */
+
+ } else {
+
+ /*
+ * Encode differential layer
+ */
+
+ for (i = 0; i < hl && y < hy; i++, y++) {
+
+ /* check whether it is worth to perform an ATMOVE */
+ if (!at_determined && c_all > 2048) {
+ cmin = clmin = 0xffffffffL;
+ cmax = clmax = 0;
+ tmax = 0;
+ for (t = 3; t <= s->mx; t++) {
+ if (c[t] > cmax) cmax = c[t];
+ if (c[t] < cmin) cmin = c[t];
+ if (c[t] > c[tmax]) tmax = t;
+ }
+ clmin = (c[0] < cmin) ? c[0] : cmin;
+ clmax = (c[0] > cmax) ? c[0] : cmax;
+ if (c_all - cmax < (c_all >> 3) &&
+ cmax - c[s->tx[plane]] > c_all - cmax &&
+ cmax - c[s->tx[plane]] > (c_all >> 4) &&
+ /* ^ T.82 said < here, fixed in Cor.1/25 */
+ cmax - (c_all - c[s->tx[plane]]) > c_all - cmax &&
+ cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) &&
+ cmax - cmin > (c_all >> 2) &&
+ (s->tx[plane] || clmax - clmin > (c_all >> 3))) {
+ /* we have decided to perform an ATMOVE */
+ new_tx = tmax;
+ if (!(s->options & JBG_DELAY_AT)) {
+ new_tx_line = i;
+ s->tx[plane] = new_tx;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n",
+ i, new_tx, c_all);
+#endif
+ }
+ at_determined = 1;
+ }
+
+ if ((i >> 1) >= ll - 1 || (y >> 1) >= ly - 1)
+ lp1 = lp2;
+
+ /* typical prediction */
+ if (s->options & JBG_TPDON && (i & 1) == 0) {
+ q1 = lp1; q2 = lp2;
+ p0 = p1 = hp;
+ if (i < hl - 1 && y < hy - 1)
+ p0 = hp + hbpl;
+ if (y > 1)
+ line_l3 = (long)*(q2 - lbpl) << 8;
+ else
+ line_l3 = 0;
+ line_l2 = (long)*q2 << 8;
+ line_l1 = (long)*q1 << 8;
+ ltp = 1;
+ for (j = 0; j < lx && ltp; q1++, q2++) {
+ if (j < lbpl * 8 - 8) {
+ if (y > 1)
+ line_l3 |= *(q2 - lbpl + 1);
+ line_l2 |= *(q2 + 1);
+ line_l1 |= *(q1 + 1);
+ }
+ do {
+ if ((j >> 2) < hbpl) {
+ line_h1 = *(p1++);
+ line_h0 = *(p0++);
+ }
+ do {
+ line_l3 <<= 1;
+ line_l2 <<= 1;
+ line_l1 <<= 1;
+ line_h1 <<= 2;
+ line_h0 <<= 2;
+ cx = (((line_l3 >> 15) & 0x007) |
+ ((line_l2 >> 12) & 0x038) |
+ ((line_l1 >> 9) & 0x1c0));
+ if (cx == 0x000)
+ if ((line_h1 & 0x300) == 0 && (line_h0 & 0x300) == 0)
+ s->tp[j] = 0;
+ else {
+ ltp = 0;
+#ifdef DEBUG
+ tp_exceptions++;
+#endif
+ }
+ else if (cx == 0x1ff)
+ if ((line_h1 & 0x300) == 0x300 && (line_h0 & 0x300) == 0x300)
+ s->tp[j] = 1;
+ else {
+ ltp = 0;
+#ifdef DEBUG
+ tp_exceptions++;
+#endif
+ }
+ else
+ s->tp[j] = 2;
+ } while (++j & 3 && j < lx);
+ } while (j & 7 && j < lx);
+ } /* for (j = ...) */
+ arith_encode(se, TPDCX, !ltp);
+#ifdef DEBUG
+ tp_lines += ltp;
+#endif
+ }
+
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the high resolution neighbour pixels of the currently coded
+ * highres pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 7654321X 76543210 line_h1
+ *
+ * Layout of the variables line_l1, line_l2, line_l3, which contain
+ * the low resolution pixels near the currently coded pixel as bits.
+ * The lowres pixel in which the currently coded highres pixel is
+ * located is marked as Y:
+ *
+ * 76543210 76543210 76543210 76543210 line_l3
+ * 76543210 7654321Y 76543210 76543210 line_l2
+ * 76543210 76543210 76543210 76543210 line_l1
+ */
+
+
+ line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0;
+ if (y > 0) line_h2 = (long)*(hp - hbpl) << 8;
+ if (y > 1) {
+ line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+ line_l3 = (long)*(lp2 - lbpl) << 8;
+ }
+ line_l2 = (long)*lp2 << 8;
+ line_l1 = (long)*lp1 << 8;
+
+ /* encode line */
+ for (j = 0; j < hx; lp1++, lp2++) {
+ if ((j >> 1) < lbpl * 8 - 8) {
+ if (y > 1)
+ line_l3 |= *(lp2 - lbpl + 1);
+ line_l2 |= *(lp2 + 1);
+ line_l1 |= *(lp1 + 1);
+ }
+ do { /* ... while (j & 15 && j < hx) */
+
+ assert(hp - (s->lhp[s->highres[plane]][plane] +
+ (stripe * hl + i) * hbpl)
+ == (ptrdiff_t) j >> 3);
+
+ assert(lp2 - (s->lhp[1-s->highres[plane]][plane] +
+ (stripe * ll + (i>>1)) * lbpl)
+ == (ptrdiff_t) j >> 4);
+
+ line_h1 |= *hp;
+ if (j < hbpl * 8 - 8) {
+ if (y > 0) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (y > 1)
+ line_h3 |= *(hp - hbpl - hbpl + 1);
+ }
+ }
+ do { /* ... while (j & 7 && j < hx) */
+ line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1;
+ if (ltp && s->tp[j >> 1] < 2) {
+ /* pixel are typical and have not to be encoded */
+ line_h1 <<= 2; line_h2 <<= 2; line_h3 <<= 2;
+#ifdef DEBUG
+ do {
+ ++tp_pixels;
+ } while (++j & 1 && j < hx);
+#else
+ j += 2;
+#endif
+ } else
+ do { /* ... while (++j & 1 && j < hx) */
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+
+ /* deterministic prediction */
+ if (s->options & JBG_DPON) {
+ if ((y & 1) == 0) {
+ if ((j & 1) == 0) {
+ /* phase 0 */
+ if (s->dppriv[((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x010) |
+ ((line_h2 >> 10) & 0x0e0)] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ } else {
+ /* phase 1 */
+ if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x030) |
+ ((line_h2 >> 10) & 0x1c0)) + 256] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ }
+ } else {
+ if ((j & 1) == 0) {
+ /* phase 2 */
+ if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x010) |
+ ((line_h2 >> 10) & 0x0e0) |
+ ((line_h3 >> 7) & 0x700)) + 768] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ } else {
+ /* phase 3 */
+ if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x030) |
+ ((line_h2 >> 10) & 0x1c0) |
+ ((line_h3 >> 7) & 0xe00)) + 2816] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ }
+ }
+ }
+
+ /* determine context */
+ if (s->tx[plane]) {
+ if ((unsigned) s->tx[plane] > j)
+ a = 0;
+ else {
+ o = (j - s->tx[plane]) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(s->tx[plane] > 23 ||
+ a == ((line_h1 >> (4 + s->tx[plane])) & 0x010));
+ cx = (((line_h1 >> 9) & 0x003) | a |
+ ((line_h2 >> 13) & 0x00c) |
+ ((line_h3 >> 11) & 0x020));
+ } else
+ cx = (((line_h1 >> 9) & 0x003) |
+ ((line_h2 >> 13) & 0x01c) |
+ ((line_h3 >> 11) & 0x020));
+ if (j & 1)
+ cx |= (((line_l2 >> 9) & 0x0c0) |
+ ((line_l1 >> 7) & 0x300)) | (1UL << 10);
+ else
+ cx |= (((line_l2 >> 10) & 0x0c0) |
+ ((line_l1 >> 8) & 0x300));
+ cx |= (y & 1) << 11;
+
+ arith_encode(se, cx, (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+
+ /* statistics for adaptive template changes */
+ if (!at_determined && j >= s->mx) {
+ c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100);
+ for (t = 3; t <= s->mx; t++)
+ c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100);
+ ++c_all;
+ }
+
+ } while (++j & 1 && j < hx);
+ } while (j & 7 && j < hx);
+ hp++;
+ } while (j & 15 && j < hx);
+ } /* for (j = ...) */
+
+ /* low resolution pixels are used twice */
+ if ((i & 1) == 0) {
+ lp1 -= lbpl;
+ lp2 -= lbpl;
+ }
+
+ } /* for (i = ...) */
+ }
+
+ arith_encode_flush(se);
+ jbg_buf_remove_zeros(s->sde[stripe][layer][plane]);
+ jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]);
+ jbg_buf_write(MARKER_SDNORM, s->sde[stripe][layer][plane]);
+
+ /* add ATMOVE */
+ if (new_tx != -1) {
+ if (s->options & JBG_DELAY_AT) {
+ /* ATMOVE will become active at the first line of the next stripe */
+ s->tx[plane] = new_tx;
+ jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]);
+ jbg_buf_write(MARKER_ATMOVE, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(s->tx[plane], s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ } else {
+ /* ATMOVE has already become active during this stripe
+ * => we have to prefix the SDE data with an ATMOVE marker */
+ new_jbg_buf = jbg_buf_init(&s->free_list);
+ jbg_buf_write(MARKER_ESC, new_jbg_buf);
+ jbg_buf_write(MARKER_ATMOVE, new_jbg_buf);
+ jbg_buf_write((new_tx_line >> 24) & 0xff, new_jbg_buf);
+ jbg_buf_write((new_tx_line >> 16) & 0xff, new_jbg_buf);
+ jbg_buf_write((new_tx_line >> 8) & 0xff, new_jbg_buf);
+ jbg_buf_write(new_tx_line & 0xff, new_jbg_buf);
+ jbg_buf_write(new_tx, new_jbg_buf);
+ jbg_buf_write(0, new_jbg_buf);
+ jbg_buf_prefix(new_jbg_buf, &s->sde[stripe][layer][plane]);
+ }
+ }
+
+#if 0
+ if (stripe == s->stripes - 1)
+ fprintf(stderr, "tp_lines = %ld, tp_exceptions = %ld, tp_pixels = %ld, "
+ "dp_pixels = %ld, encoded_pixels = %ld\n",
+ tp_lines, tp_exceptions, tp_pixels, dp_pixels, encoded_pixels);
+#endif
+
+ return;
+}
+
+
+/*
+ * Create the next lower resolution version of an image
+ */
+static void resolution_reduction(struct jbg_enc_state *s, int plane,
+ int higher_layer)
+{
+ unsigned long hx, hy, lx, ly, hbpl, lbpl;
+ unsigned char *hp1, *hp2, *hp3, *lp;
+ unsigned long line_h1, line_h2, line_h3, line_l2;
+ unsigned long i, j;
+ int pix, k, l;
+
+ /* number of pixels in highres image */
+ hx = jbg_ceil_half(s->xd, s->d - higher_layer);
+ hy = jbg_ceil_half(s->yd, s->d - higher_layer);
+ /* number of pixels in lowres image */
+ lx = jbg_ceil_half(hx, 1);
+ ly = jbg_ceil_half(hy, 1);
+ /* bytes per line in highres and lowres image */
+ hbpl = jbg_ceil_half(hx, 3);
+ lbpl = jbg_ceil_half(lx, 3);
+ /* pointers to first image bytes */
+ hp2 = s->lhp[s->highres[plane]][plane];
+ hp1 = hp2 + hbpl;
+ hp3 = hp2 - hbpl;
+ lp = s->lhp[1 - s->highres[plane]][plane];
+
+#ifdef DEBUG
+ fprintf(stderr, "resolution_reduction: plane = %d, higher_layer = %d\n",
+ plane, higher_layer);
+#endif
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the high resolution neighbour pixels of the currently coded
+ * lowres pixel /\:
+ * \/
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 765432/\ 76543210 line_h2
+ * 76543210 76543210 765432\/ 76543210 line_h1
+ *
+ * Layout of the variable line_l2, which contains the low resolution
+ * pixels near the currently coded pixel as bits. The lowres pixel
+ * which is currently coded is marked as X:
+ *
+ * 76543210 76543210 76543210 76543210 line_l2
+ * X
+ */
+
+ for (i = 0; i < ly; i++) {
+ if (2*i + 1 >= hy)
+ hp1 = hp2;
+ pix = 0;
+ line_h1 = line_h2 = line_h3 = line_l2 = 0;
+ for (j = 0; j < lbpl * 8; j += 8) {
+ *lp = 0;
+ line_l2 |= i ? *(lp-lbpl) : 0;
+ for (k = 0; k < 8 && j + k < lx; k += 4) {
+ if (((j + k) >> 2) < hbpl) {
+ line_h3 |= i ? *hp3 : 0;
+ ++hp3;
+ line_h2 |= *(hp2++);
+ line_h1 |= *(hp1++);
+ }
+ for (l = 0; l < 4 && j + k + l < lx; l++) {
+ line_h3 <<= 2;
+ line_h2 <<= 2;
+ line_h1 <<= 2;
+ line_l2 <<= 1;
+ pix = s->res_tab[((line_h1 >> 8) & 0x007) |
+ ((line_h2 >> 5) & 0x038) |
+ ((line_h3 >> 2) & 0x1c0) |
+ (pix << 9) | ((line_l2 << 2) & 0xc00)];
+ *lp = (*lp << 1) | pix;
+ }
+ }
+ ++lp;
+ }
+ *(lp - 1) <<= lbpl * 8 - lx;
+ hp1 += hbpl;
+ hp2 += hbpl;
+ hp3 += hbpl;
+ }
+
+#ifdef DEBUG
+ {
+ FILE *f;
+ char fn[50];
+
+ sprintf(fn, "dbg_d=%02d.pbm", higher_layer - 1);
+ f = fopen(fn, "wb");
+ fprintf(f, "P4\n%lu %lu\n", lx, ly);
+ fwrite(s->lhp[1 - s->highres[plane]][plane], 1, lbpl * ly, f);
+ fclose(f);
+ }
+#endif
+
+ return;
+}
+
+
+/*
+ * This function is called inside the three loops of jbg_enc_out() in
+ * order to write the next SDE. It has first to generate the required
+ * SDE and all SDEs which have to be encoded before this SDE can be
+ * created. The problem here is that if we want to output a lower
+ * resolution layer, we have to allpy the resolution reduction
+ * algorithm in order to get it. As we try to safe as much memory as
+ * possible, the resolution reduction will overwrite previous higher
+ * resolution bitmaps. Consequently, we have to encode and buffer SDEs
+ * which depend on higher resolution layers before we can start the
+ * resolution reduction. All this logic about which SDE has to be
+ * encoded before resolution reduction is allowed is handled here.
+ * This approach might be a little bit more complex than alternative
+ * ways to do it, but it allows us to do the encoding with the minimal
+ * possible amount of temporary memory.
+ */
+static void output_sde(struct jbg_enc_state *s,
+ unsigned long stripe, int layer, int plane)
+{
+ int lfcl; /* lowest fully coded layer */
+ long i;
+ unsigned long u;
+
+ assert(s->sde[stripe][layer][plane] != SDE_DONE);
+
+ if (s->sde[stripe][layer][plane] != SDE_TODO) {
+#ifdef DEBUG
+ fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n",
+ stripe, layer, plane);
+#endif
+ jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file);
+ s->sde[stripe][layer][plane] = SDE_DONE;
+ return;
+ }
+
+ /* Determine the smallest resolution layer in this plane for which
+ * not yet all stripes have been encoded into SDEs. This layer will
+ * have to be completely coded, before we can apply the next
+ * resolution reduction step. */
+ lfcl = 0;
+ for (i = s->d; i >= 0; i--)
+ if (s->sde[s->stripes - 1][i][plane] == SDE_TODO) {
+ lfcl = i + 1;
+ break;
+ }
+ if (lfcl > s->d && s->d > 0 && stripe == 0) {
+ /* perform the first resolution reduction */
+ resolution_reduction(s, plane, s->d);
+ }
+ /* In case HITOLO is not used, we have to encode and store the higher
+ * resolution layers first, although we do not need them right now. */
+ while (lfcl - 1 > layer) {
+ for (u = 0; u < s->stripes; u++)
+ encode_sde(s, u, lfcl - 1, plane);
+ --lfcl;
+ s->highres[plane] ^= 1;
+ if (lfcl > 1)
+ resolution_reduction(s, plane, lfcl - 1);
+ }
+
+ encode_sde(s, stripe, layer, plane);
+
+#ifdef DEBUG
+ fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", stripe, layer, plane);
+#endif
+ jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file);
+ s->sde[stripe][layer][plane] = SDE_DONE;
+
+ if (stripe == s->stripes - 1 && layer > 0 &&
+ s->sde[0][layer-1][plane] == SDE_TODO) {
+ s->highres[plane] ^= 1;
+ if (layer > 1)
+ resolution_reduction(s, plane, layer - 1);
+ }
+
+ return;
+}
+
+
+/*
+ * Convert the table which controls the deterministic prediction
+ * process from the internal format into the representation required
+ * for the 1728 byte long DPTABLE element of a BIH.
+ *
+ * The bit order of the DPTABLE format (see also ITU-T T.82 figure 13) is
+ *
+ * high res: 4 5 6 low res: 0 1
+ * 7 8 9 2 3
+ * 10 11 12
+ *
+ * were 4 table entries are packed into one byte, while we here use
+ * internally an unpacked 6912 byte long table indexed by the following
+ * bit order:
+ *
+ * high res: 7 6 5 high res: 8 7 6 low res: 1 0
+ * (phase 0) 4 . . (phase 1) 5 4 . 3 2
+ * . . . . . .
+ *
+ * high res: 10 9 8 high res: 11 10 9
+ * (phase 2) 7 6 5 (phase 3) 8 7 6
+ * 4 . . 5 4 .
+ */
+void jbg_int2dppriv(unsigned char *dptable, const char *internal)
+{
+ int i, j, k;
+ int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 };
+ int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 };
+ int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 };
+ int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 };
+
+ for (i = 0; i < 1728; dptable[i++] = 0);
+
+#define FILL_TABLE1(offset, len, trans) \
+ for (i = 0; i < len; i++) { \
+ k = 0; \
+ for (j = 0; j < 8; j++) \
+ k |= ((i >> j) & 1) << trans[j]; \
+ dptable[(i + offset) >> 2] |= \
+ (internal[k + offset] & 3) << ((3 - (i&3)) << 1); \
+ }
+
+ FILL_TABLE1( 0, 256, trans0);
+ FILL_TABLE1( 256, 512, trans1);
+ FILL_TABLE1( 768, 2048, trans2);
+ FILL_TABLE1(2816, 4096, trans3);
+
+ return;
+}
+
+
+/*
+ * Convert the table which controls the deterministic prediction
+ * process from the 1728 byte long DPTABLE format into the 6912 byte long
+ * internal format.
+ */
+void jbg_dppriv2int(char *internal, const unsigned char *dptable)
+{
+ int i, j, k;
+ int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 };
+ int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 };
+ int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 };
+ int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 };
+
+#define FILL_TABLE2(offset, len, trans) \
+ for (i = 0; i < len; i++) { \
+ k = 0; \
+ for (j = 0; j < 8; j++) \
+ k |= ((i >> j) & 1) << trans[j]; \
+ internal[k + offset] = \
+ (dptable[(i + offset) >> 2] >> ((3 - (i & 3)) << 1)) & 3; \
+ }
+
+ FILL_TABLE2( 0, 256, trans0);
+ FILL_TABLE2( 256, 512, trans1);
+ FILL_TABLE2( 768, 2048, trans2);
+ FILL_TABLE2(2816, 4096, trans3);
+
+ return;
+}
+
+
+/*
+ * Encode one full BIE and pass the generated data to the specified
+ * call-back function
+ */
+void jbg_enc_out(struct jbg_enc_state *s)
+{
+ unsigned long bpl;
+ unsigned char buf[20];
+ unsigned long xd, yd, y;
+ long ii[3], is[3], ie[3]; /* generic variables for the 3 nested loops */
+ unsigned long stripe;
+ int layer, plane;
+ int order;
+ unsigned char dpbuf[1728];
+ extern char jbg_dptable[];
+
+ /* some sanity checks */
+ s->order &= JBG_HITOLO | JBG_SEQ | JBG_ILEAVE | JBG_SMID;
+ order = s->order & (JBG_SEQ | JBG_ILEAVE | JBG_SMID);
+ if (iindex[order][0] < 0)
+ s->order = order = JBG_SMID | JBG_ILEAVE;
+ if (s->options & JBG_DPON && s->dppriv != jbg_dptable)
+ s->options |= JBG_DPPRIV;
+ if (s->mx > MX_MAX)
+ s->mx = MX_MAX;
+ s->my = 0;
+ if (s->mx && s->mx < ((s->options & JBG_LRLTWO) ? 5U : 3U))
+ s->mx = 0;
+ if (s->d > 255 || s->d < 0 || s->dh > s->d || s->dh < 0 ||
+ s->dl < 0 || s->dl > s->dh || s->planes < 0 || s->planes > 255)
+ return;
+ /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+ if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+ return;
+ if (s->yd1 < s->yd)
+ s->yd1 = s->yd;
+ if (s->yd1 > s->yd)
+ s->options |= JBG_VLENGTH;
+
+ /* ensure correct zero padding of bitmap at the final byte of each line */
+ if (s->xd & 7) {
+ bpl = jbg_ceil_half(s->xd, 3); /* bytes per line */
+ for (plane = 0; plane < s->planes; plane++)
+ for (y = 0; y < s->yd; y++)
+ s->lhp[0][plane][y * bpl + bpl - 1] &= ~((1 << (8 - (s->xd & 7))) - 1);
+ }
+
+ /* prepare BIH */
+ buf[0] = s->dl;
+ buf[1] = s->dh;
+ buf[2] = s->planes;
+ buf[3] = 0;
+ xd = jbg_ceil_half(s->xd, s->d - s->dh);
+ yd = jbg_ceil_half(s->yd1, s->d - s->dh);
+ buf[4] = xd >> 24;
+ buf[5] = (xd >> 16) & 0xff;
+ buf[6] = (xd >> 8) & 0xff;
+ buf[7] = xd & 0xff;
+ buf[8] = yd >> 24;
+ buf[9] = (yd >> 16) & 0xff;
+ buf[10] = (yd >> 8) & 0xff;
+ buf[11] = yd & 0xff;
+ buf[12] = s->l0 >> 24;
+ buf[13] = (s->l0 >> 16) & 0xff;
+ buf[14] = (s->l0 >> 8) & 0xff;
+ buf[15] = s->l0 & 0xff;
+ buf[16] = s->mx;
+ buf[17] = s->my;
+ buf[18] = s->order;
+ buf[19] = s->options & 0x7f;
+
+#if 0
+ /* sanitize L0 (if it was set to 0xffffffff for T.85-style NEWLEN tests) */
+ if (s->l0 > (s->yd >> s->d))
+ s->l0 = s->yd >> s->d;
+#endif
+
+ /* calculate number of stripes that will be required */
+ s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+
+ /* allocate buffers for SDE pointers */
+ if (s->sde == NULL) {
+ s->sde = (struct jbg_buf ****)
+ checked_malloc(s->stripes, sizeof(struct jbg_buf ***));
+ for (stripe = 0; stripe < s->stripes; stripe++) {
+ s->sde[stripe] = (struct jbg_buf ***)
+ checked_malloc(s->d + 1, sizeof(struct jbg_buf **));
+ for (layer = 0; layer < s->d + 1; layer++) {
+ s->sde[stripe][layer] = (struct jbg_buf **)
+ checked_malloc(s->planes, sizeof(struct jbg_buf *));
+ for (plane = 0; plane < s->planes; plane++)
+ s->sde[stripe][layer][plane] = SDE_TODO;
+ }
+ }
+ }
+
+ /* output BIH */
+ s->data_out(buf, 20, s->file);
+ if ((s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) ==
+ (JBG_DPON | JBG_DPPRIV)) {
+ /* write private table */
+ jbg_int2dppriv(dpbuf, s->dppriv);
+ s->data_out(dpbuf, 1728, s->file);
+ }
+
+#if 0
+ /*
+ * Encode everything first. This is a simple-minded alternative to
+ * all the tricky on-demand encoding logic in output_sde() for
+ * debugging purposes.
+ */
+ for (layer = s->dh; layer >= s->dl; layer--) {
+ for (plane = 0; plane < s->planes; plane++) {
+ if (layer > 0)
+ resolution_reduction(s, plane, layer);
+ for (stripe = 0; stripe < s->stripes; stripe++)
+ encode_sde(s, stripe, layer, plane);
+ s->highres[plane] ^= 1;
+ }
+ }
+#endif
+
+ /*
+ * Generic loops over all SDEs. Which loop represents layer, plane and
+ * stripe depends on the option flags.
+ */
+
+ /* start and end value vor each loop */
+ is[iindex[order][STRIPE]] = 0;
+ ie[iindex[order][STRIPE]] = s->stripes - 1;
+ is[iindex[order][LAYER]] = s->dl;
+ ie[iindex[order][LAYER]] = s->dh;
+ is[iindex[order][PLANE]] = 0;
+ ie[iindex[order][PLANE]] = s->planes - 1;
+
+ for (ii[0] = is[0]; ii[0] <= ie[0]; ii[0]++)
+ for (ii[1] = is[1]; ii[1] <= ie[1]; ii[1]++)
+ for (ii[2] = is[2]; ii[2] <= ie[2]; ii[2]++) {
+
+ stripe = ii[iindex[order][STRIPE]];
+ if (s->order & JBG_HITOLO)
+ layer = s->dh - (ii[iindex[order][LAYER]] - s->dl);
+ else
+ layer = ii[iindex[order][LAYER]];
+ plane = ii[iindex[order][PLANE]];
+
+ output_sde(s, stripe, layer, plane);
+
+ /*
+ * When we generate a NEWLEN test case (s->yd1 > s->yd), output
+ * NEWLEN after last stripe if we have only a single
+ * resolution layer or plane (see ITU-T T.85 profile), otherwise
+ * output NEWLEN before last stripe.
+ */
+ if (s->yd1 > s->yd &&
+ (stripe == s->stripes - 1 ||
+ (stripe == s->stripes - 2 &&
+ (s->dl != s->dh || s->planes > 1)))) {
+ s->yd1 = s->yd;
+ yd = jbg_ceil_half(s->yd, s->d - s->dh);
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_NEWLEN;
+ buf[2] = yd >> 24;
+ buf[3] = (yd >> 16) & 0xff;
+ buf[4] = (yd >> 8) & 0xff;
+ buf[5] = yd & 0xff;
+ s->data_out(buf, 6, s->file);
+#ifdef DEBUG
+ fprintf(stderr, "NEWLEN: yd=%lu\n", yd);
+#endif
+ if (stripe == s->stripes - 1) {
+ buf[1] = MARKER_SDNORM;
+ s->data_out(buf, 2, s->file);
+ }
+ }
+
+ }
+
+ return;
+}
+
+
+void jbg_enc_free(struct jbg_enc_state *s)
+{
+ unsigned long stripe;
+ int layer, plane;
+
+#ifdef DEBUG
+ fprintf(stderr, "jbg_enc_free(%p)\n", (void *) s);
+#endif
+
+ /* clear buffers for SDEs */
+ if (s->sde) {
+ for (stripe = 0; stripe < s->stripes; stripe++) {
+ for (layer = 0; layer < s->d + 1; layer++) {
+ for (plane = 0; plane < s->planes; plane++)
+ if (s->sde[stripe][layer][plane] != SDE_DONE &&
+ s->sde[stripe][layer][plane] != SDE_TODO)
+ jbg_buf_free(&s->sde[stripe][layer][plane]);
+ checked_free(s->sde[stripe][layer]);
+ }
+ checked_free(s->sde[stripe]);
+ }
+ checked_free(s->sde);
+ }
+
+ /* clear free_list */
+ jbg_buf_free(&s->free_list);
+
+ /* clear memory for arithmetic encoder states */
+ checked_free(s->s);
+
+ /* clear memory for differential-layer typical prediction buffer */
+ checked_free(s->tp);
+
+ /* clear memory for adaptive template pixel offsets */
+ checked_free(s->tx);
+
+ /* clear lowres image buffers */
+ if (s->lhp[1]) {
+ for (plane = 0; plane < s->planes; plane++)
+ checked_free(s->lhp[1][plane]);
+ checked_free(s->lhp[1]);
+ }
+
+ /* clear buffer for index of highres image in lhp */
+ checked_free(s->highres);
+
+ return;
+}
+
+
+/*
+ * Convert the error codes used by jbg_dec_in() into a string
+ * written in the selected language and character set.
+ */
+const char *jbg_strerror(int errnum, int language)
+{
+ if (errnum < 0 || errnum >= NEMSG)
+ return "Unknown error code passed to jbg_strerror()";
+ if (language < 0 || language >= NEMSG_LANG)
+ return "Unknown language code passed to jbg_strerror()";
+
+ return errmsg[language][errnum];
+}
+
+
+/*
+ * The constructor for a decoder
+ */
+void jbg_dec_init(struct jbg_dec_state *s)
+{
+ s->order = 0;
+ s->d = -1;
+ s->bie_len = 0;
+ s->buf_len = 0;
+ s->dppriv = NULL;
+ s->xmax = 4294967295UL;
+ s->ymax = 4294967295UL;
+ s->dmax = 256;
+ s->s = NULL;
+
+ return;
+}
+
+
+/*
+ * Specify a maximum image size for the decoder. If the JBIG file has
+ * the order bit ILEAVE, but not the bit SEQ set, then the decoder
+ * will abort to decode after the image has reached the maximal
+ * resolution layer which is still not wider than xmax or higher than
+ * ymax.
+ */
+void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+ unsigned long ymax)
+{
+ if (xmax > 0) s->xmax = xmax;
+ if (ymax > 0) s->ymax = ymax;
+
+ return;
+}
+
+
+/*
+ * Decode the new len PSDC bytes to which data points and add them to
+ * the current stripe. Return the number of bytes which have actually
+ * been read (this will be less than len if a marker segment was
+ * part of the data or if the final byte was 0xff were this code
+ * can not determine, whether we have a marker segment.
+ */
+static size_t decode_pscd(struct jbg_dec_state *s, unsigned char *data,
+ size_t len)
+{
+ unsigned long stripe;
+ unsigned int layer, plane;
+ unsigned long hl, ll, y, hx, hy, lx, ly, hbpl, lbpl;
+ unsigned char *hp, *lp1, *lp2, *p1, *q1;
+ register unsigned long line_h1, line_h2, line_h3;
+ register unsigned long line_l1, line_l2, line_l3;
+ struct jbg_ardec_state *se;
+ unsigned long x;
+ long o;
+ unsigned a;
+ int n;
+ int pix, cx = 0, slntp, tx;
+
+ /* SDE loop variables */
+ stripe = s->ii[iindex[s->order & 7][STRIPE]];
+ layer = s->ii[iindex[s->order & 7][LAYER]];
+ plane = s->ii[iindex[s->order & 7][PLANE]];
+
+ /* forward data to arithmetic decoder */
+ se = s->s[plane] + layer - s->dl;
+ se->pscd_ptr = data;
+ se->pscd_end = data + len;
+
+ /* number of lines per stripe in highres image */
+ hl = s->l0 << layer;
+ /* number of lines per stripe in lowres image */
+ ll = hl >> 1;
+ /* current line number in highres image */
+ y = stripe * hl + s->i;
+ /* number of pixels in highres image */
+ hx = jbg_ceil_half(s->xd, s->d - layer);
+ hy = jbg_ceil_half(s->yd, s->d - layer);
+ /* number of pixels in lowres image */
+ lx = jbg_ceil_half(hx, 1);
+ ly = jbg_ceil_half(hy, 1);
+ /* bytes per line in highres and lowres image */
+ hbpl = jbg_ceil_half(hx, 3);
+ lbpl = jbg_ceil_half(lx, 3);
+ /* pointer to highres and lowres image bytes */
+ hp = s->lhp[ layer & 1][plane] + (stripe * hl + s->i) * hbpl +
+ (s->x >> 3);
+ lp2 = s->lhp[(layer-1) & 1][plane] + (stripe * ll + (s->i >> 1)) * lbpl +
+ (s->x >> 4);
+ lp1 = lp2 + lbpl;
+
+ /* restore a few local variables */
+ line_h1 = s->line_h1;
+ line_h2 = s->line_h2;
+ line_h3 = s->line_h3;
+ line_l1 = s->line_l1;
+ line_l2 = s->line_l2;
+ line_l3 = s->line_l3;
+ x = s->x;
+
+ if (s->x == 0 && s->i == 0 &&
+ (stripe == 0 || s->reset[plane][layer - s->dl])) {
+ s->tx[plane][layer - s->dl] = s->ty[plane][layer - s->dl] = 0;
+ if (s->pseudo)
+ s->lntp[plane][layer - s->dl] = 1;
+ }
+
+#ifdef DEBUG
+ if (s->x == 0 && s->i == 0 && s->pseudo)
+ fprintf(stderr, "decode_pscd(%p, %p, %ld): s/d/p = %2lu/%2u/%2u\n",
+ (void *) s, (void *) data, (long) len, stripe, layer, plane);
+#endif
+
+ if (layer == 0) {
+
+ /*
+ * Decode lowest resolution layer
+ */
+
+ for (; s->i < hl && y < hy; s->i++, y++) {
+
+ /* adaptive template changes */
+ if (x == 0)
+ for (n = 0; n < s->at_moves; n++)
+ if (s->at_line[n] == s->i) {
+ s->tx[plane][layer - s->dl] = s->at_tx[n];
+ s->ty[plane][layer - s->dl] = s->at_ty[n];
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,
+ s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);
+#endif
+ }
+ tx = s->tx[plane][layer - s->dl];
+ assert(tx >= 0); /* i.e., tx can safely be cast to unsigned */
+
+ /* typical prediction */
+ if (s->options & JBG_TPBON && s->pseudo) {
+ slntp = arith_decode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX);
+ if (se->result == JBG_MORE || se->result == JBG_MARKER)
+ goto leave;
+ s->lntp[plane][layer - s->dl] =
+ !(slntp ^ s->lntp[plane][layer - s->dl]);
+ if (s->lntp[plane][layer - s->dl]) {
+ /* this line is 'not typical' and has to be coded completely */
+ s->pseudo = 0;
+ } else {
+ /* this line is 'typical' (i.e. identical to the previous one) */
+ p1 = hp;
+ if (s->i == 0 && (stripe == 0 || s->reset[plane][layer - s->dl]))
+ while (p1 < hp + hbpl) *p1++ = 0;
+ else {
+ q1 = hp - hbpl;
+ while (q1 < hp) *p1++ = *q1++;
+ }
+ hp += hbpl;
+ continue;
+ }
+ }
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the neighbour pixels of the currently decoded pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 76543210 76543210 X line_h1
+ */
+
+ if (x == 0) {
+ line_h1 = line_h2 = line_h3 = 0;
+ if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))
+ line_h2 = (long)*(hp - hbpl) << 8;
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+ }
+
+ /*
+ * Another tiny JBIG standard bug:
+ *
+ * While implementing the line_h3 handling here, I discovered
+ * another problem with the ITU-T T.82(1993 E) specification.
+ * This might be a somewhat pathological case, however. The
+ * standard is unclear about how a decoder should behave in the
+ * following situation:
+ *
+ * Assume we are in layer 0 and all stripes are single lines
+ * (L0=1 allowed by table 9). We are now decoding the first (and
+ * only) line of the third stripe. Assume, the first stripe was
+ * terminated by SDRST and the second stripe was terminated by
+ * SDNORM. While decoding the only line of the third stripe with
+ * the three-line template, we need access to pixels from the
+ * previous two stripes. We know that the previous stripe
+ * terminated with SDNROM, so we access the pixel from the
+ * second stripe. But do we have to replace the pixels from the
+ * first stripe by background pixels, because this stripe ended
+ * with SDRST? The standard, especially clause 6.2.5 does never
+ * mention this case, so the behaviour is undefined here. My
+ * current implementation remembers only the marker used to
+ * terminate the previous stripe. In the above example, the
+ * pixels of the first stripe are accessed despite the fact that
+ * this stripe ended with SDRST. An alternative (only slightly
+ * more complicated) implementation would be to remember the end
+ * marker (SDNORM or SDRST) of the previous two stripes in a
+ * plane/layer and to act accordingly when accessing the two
+ * previous lines. What am I supposed to do here?
+ *
+ * As the standard is unclear about the correct behaviour in the
+ * situation of the above example, I strongly suggest to avoid
+ * the following situation while encoding data with JBIG:
+ *
+ * LRLTWO = 0, L0=1 and both SDNORM and SDRST appear in layer 0.
+ *
+ * I guess that only a very few if any encoders will switch
+ * between SDNORM and SDRST, so let us hope that this ambiguity
+ * in the standard will never cause any interoperability
+ * problems.
+ *
+ * Markus Kuhn -- 1995-04-30
+ */
+
+ /* decode line */
+ while (x < hx) {
+ if ((x & 7) == 0) {
+ if (x < hbpl * 8 - 8 &&
+ (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 |= *(hp - hbpl - hbpl + 1);
+ }
+ }
+ if (s->options & JBG_LRLTWO) {
+ /* two line template */
+ do {
+ if (tx) {
+ if ((unsigned) tx > x)
+ a = 0;
+ else if (tx < 8)
+ a = ((line_h1 >> (tx - 5)) & 0x010);
+ else {
+ o = (x - tx) - (x & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(tx > 31 ||
+ a == ((line_h1 >> (tx - 5)) & 0x010));
+ pix = arith_decode(se, (((line_h2 >> 9) & 0x3e0) | a |
+ (line_h1 & 0x00f)));
+ } else
+ pix = arith_decode(se, (((line_h2 >> 9) & 0x3f0) |
+ (line_h1 & 0x00f)));
+ if (se->result == JBG_MORE || se->result == JBG_MARKER)
+ goto leave;
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ } while ((++x & 7) && x < hx);
+ } else {
+ /* three line template */
+ do {
+ if (tx) {
+ if ((unsigned) tx > x)
+ a = 0;
+ else if (tx < 8)
+ a = ((line_h1 >> (tx - 3)) & 0x004);
+ else {
+ o = (x - tx) - (x & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 2;
+ }
+ assert(tx > 31 ||
+ a == ((line_h1 >> (tx - 3)) & 0x004));
+ pix = arith_decode(se, (((line_h3 >> 7) & 0x380) |
+ ((line_h2 >> 11) & 0x078) | a |
+ (line_h1 & 0x003)));
+ } else
+ pix = arith_decode(se, (((line_h3 >> 7) & 0x380) |
+ ((line_h2 >> 11) & 0x07c) |
+ (line_h1 & 0x003)));
+ if (se->result == JBG_MORE || se->result == JBG_MARKER)
+ goto leave;
+
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ line_h3 <<= 1;
+ } while ((++x & 7) && x < hx);
+ } /* if (s->options & JBG_LRLTWO) */
+ *hp++ = line_h1;
+ } /* while */
+ *(hp - 1) <<= hbpl * 8 - hx;
+ x = 0;
+ s->pseudo = 1;
+ } /* for (i = ...) */
+
+ } else {
+
+ /*
+ * Decode differential layer
+ */
+
+ for (; s->i < hl && y < hy; s->i++, y++) {
+
+ /* adaptive template changes */
+ if (x == 0)
+ for (n = 0; n < s->at_moves; n++)
+ if (s->at_line[n] == s->i) {
+ s->tx[plane][layer - s->dl] = s->at_tx[n];
+ s->ty[plane][layer - s->dl] = s->at_ty[n];
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,
+ s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);
+#endif
+ }
+ tx = s->tx[plane][layer - s->dl];
+
+ /* handle lower border of low-resolution image */
+ if ((s->i >> 1) >= ll - 1 || (y >> 1) >= ly - 1)
+ lp1 = lp2;
+
+ /* typical prediction */
+ if (s->options & JBG_TPDON && s->pseudo) {
+ s->lntp[plane][layer - s->dl] = arith_decode(se, TPDCX);
+ if (se->result == JBG_MORE || se->result == JBG_MARKER)
+ goto leave;
+ s->pseudo = 0;
+ }
+
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the high resolution neighbour pixels of the currently
+ * decoded highres pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 76543210 76543210 X line_h1
+ *
+ * Layout of the variables line_l1, line_l2, line_l3, which contain
+ * the low resolution pixels near the currently decoded pixel as bits.
+ * The lowres pixel in which the currently coded highres pixel is
+ * located is marked as Y:
+ *
+ * 76543210 76543210 76543210 76543210 line_l3
+ * 76543210 76543210 Y6543210 76543210 line_l2
+ * 76543210 76543210 76543210 76543210 line_l1
+ */
+
+
+ if (x == 0) {
+ line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0;
+ if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) {
+ line_h2 = (long)*(hp - hbpl) << 8;
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+ }
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer-s->dl]))
+ line_l3 = (long)*(lp2 - lbpl) << 8;
+ line_l2 = (long)*lp2 << 8;
+ line_l1 = (long)*lp1 << 8;
+ }
+
+ /* decode line */
+ while (x < hx) {
+ if ((x & 15) == 0)
+ if ((x >> 1) < lbpl * 8 - 8) {
+ line_l1 |= *(lp1 + 1);
+ line_l2 |= *(lp2 + 1);
+ if (s->i > 1 ||
+ (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_l3 |= *(lp2 - lbpl + 1);
+ }
+ do {
+
+ assert(hp - (s->lhp[ layer &1][plane] + (stripe * hl + s->i)
+ * hbpl) == (ptrdiff_t) x >> 3);
+ assert(lp2 - (s->lhp[(layer-1) &1][plane] + (stripe * ll + (s->i>>1))
+ * lbpl) == (ptrdiff_t) x >> 4);
+
+ if ((x & 7) == 0)
+ if (x < hbpl * 8 - 8) {
+ if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) {
+ line_h2 |= *(hp + 1 - hbpl);
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 |= *(hp + 1 - hbpl - hbpl);
+ }
+ }
+ do {
+ if (!s->lntp[plane][layer - s->dl])
+ cx = (((line_l3 >> 14) & 0x007) |
+ ((line_l2 >> 11) & 0x038) |
+ ((line_l1 >> 8) & 0x1c0));
+ if (!s->lntp[plane][layer - s->dl] &&
+ (cx == 0x000 || cx == 0x1ff)) {
+ /* pixels are typical and have not to be decoded */
+ do {
+ line_h1 = (line_h1 << 1) | (cx & 1);
+ } while ((++x & 1) && x < hx);
+ line_h2 <<= 2; line_h3 <<= 2;
+ } else
+ do {
+
+ /* deterministic prediction */
+ if (s->options & JBG_DPON)
+ if ((y & 1) == 0)
+ if ((x & 1) == 0)
+ /* phase 0 */
+ pix = s->dppriv[((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x010) |
+ ((line_h2 >> 9) & 0x0e0)];
+ else
+ /* phase 1 */
+ pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x030) |
+ ((line_h2 >> 9) & 0x1c0)) + 256];
+ else
+ if ((x & 1) == 0)
+ /* phase 2 */
+ pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x010) |
+ ((line_h2 >> 9) & 0x0e0) |
+ ((line_h3 >> 6) & 0x700)) + 768];
+ else
+ /* phase 3 */
+ pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x030) |
+ ((line_h2 >> 9) & 0x1c0) |
+ ((line_h3 >> 6) & 0xe00)) + 2816];
+ else
+ pix = 2;
+
+ if (pix & 2) {
+ if (tx)
+ cx = ((line_h1 & 0x003) |
+ (((line_h1 << 2) >> (tx - 3)) & 0x010) |
+ ((line_h2 >> 12) & 0x00c) |
+ ((line_h3 >> 10) & 0x020));
+ else
+ cx = ((line_h1 & 0x003) |
+ ((line_h2 >> 12) & 0x01c) |
+ ((line_h3 >> 10) & 0x020));
+ if (x & 1)
+ cx |= (((line_l2 >> 8) & 0x0c0) |
+ ((line_l1 >> 6) & 0x300)) | (1UL << 10);
+ else
+ cx |= (((line_l2 >> 9) & 0x0c0) |
+ ((line_l1 >> 7) & 0x300));
+ cx |= (y & 1) << 11;
+
+ pix = arith_decode(se, cx);
+ if (se->result == JBG_MORE || se->result == JBG_MARKER)
+ goto leave;
+ }
+
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ line_h3 <<= 1;
+
+ } while ((++x & 1) && x < hx);
+ line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1;
+ } while ((x & 7) && x < hx);
+ *hp++ = line_h1;
+ } while ((x & 15) && x < hx);
+ ++lp1;
+ ++lp2;
+ } /* while */
+ x = 0;
+
+ *(hp - 1) <<= hbpl * 8 - hx;
+ if ((s->i & 1) == 0) {
+ /* low resolution pixels are used twice */
+ lp1 -= lbpl;
+ lp2 -= lbpl;
+ } else
+ s->pseudo = 1;
+
+ } /* for (i = ...) */
+
+ }
+
+ leave:
+
+ /* save a few local variables */
+ s->line_h1 = line_h1;
+ s->line_h2 = line_h2;
+ s->line_h3 = line_h3;
+ s->line_l1 = line_l1;
+ s->line_l2 = line_l2;
+ s->line_l3 = line_l3;
+ s->x = x;
+
+ return se->pscd_ptr - data;
+}
+
+
+/*
+ * Provide a new BIE fragment to the decoder.
+ *
+ * If cnt is not NULL, then *cnt will contain after the call the
+ * number of actually read bytes. If the data was not complete, then
+ * the return value will be JBG_EAGAIN and *cnt == len. In case this
+ * function has returned with JBG_EOK, then it has reached the end of
+ * a BIE but it can be called again with data from the next BIE if
+ * there exists one in order to get to a higher resolution layer. In
+ * case the return value was JBG_EOK_INTR then this function can be
+ * called again with the rest of the BIE, because parsing the BIE has
+ * been interrupted by a jbg_dec_maxsize() specification. In both
+ * cases the remaining len - *cnt bytes of the previous block will
+ * have to passed to this function again (if len > *cnt). In case of
+ * any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN, a
+ * serious problem has occured and the only function you should call
+ * is jbg_dec_free() in order to remove the mess (and probably
+ * jbg_strerror() in order to find out what to tell the user).
+ */
+int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt)
+{
+ int i, j, required_length;
+ unsigned long x, y;
+ unsigned long is[3], ie[3];
+ extern char jbg_dptable[];
+ size_t dummy_cnt;
+
+ if (!cnt) cnt = &dummy_cnt;
+ *cnt = 0;
+ if (len < 1) return JBG_EAGAIN;
+
+ /* read in 20-byte BIH */
+ if (s->bie_len < 20) {
+ while (s->bie_len < 20 && *cnt < len)
+ s->buffer[s->bie_len++] = data[(*cnt)++];
+ if (s->bie_len < 20)
+ return JBG_EAGAIN;
+ if (s->buffer[1] < s->buffer[0])
+ return JBG_EINVAL;
+ /* test whether this looks like a valid JBIG header at all */
+ if (s->buffer[3] != 0 || (s->buffer[18] & 0xf0) != 0 ||
+ (s->buffer[19] & 0x80) != 0)
+ return JBG_EINVAL;
+ if (s->buffer[0] != s->d + 1)
+ return JBG_ENOCONT;
+ s->dl = s->buffer[0];
+ s->d = s->buffer[1];
+ if (s->dl == 0)
+ s->planes = s->buffer[2];
+ else
+ if (s->planes != s->buffer[2])
+ return JBG_ENOCONT;
+ x = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) |
+ ((long) s->buffer[ 6] << 8) | (long) s->buffer[ 7]);
+ y = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) |
+ ((long) s->buffer[10] << 8) | (long) s->buffer[11]);
+ if (s->dl != 0 && ((s->xd << (s->d - s->dl + 1)) != x &&
+ (s->yd << (s->d - s->dl + 1)) != y))
+ return JBG_ENOCONT;
+ s->xd = x;
+ s->yd = y;
+ s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) |
+ ((long) s->buffer[14] << 8) | (long) s->buffer[15]);
+ /* ITU-T T.85 trick not directly supported by decoder; for full
+ * T.85 compatibility with respect to all NEWLEN marker scenarios,
+ * preprocess BIE with jbg_newlen() before passing it to the decoder. */
+ if (s->yd == 0xffffffff)
+ return JBG_EIMPL;
+ if (!s->planes || !s->xd || !s->yd || !s->l0)
+ return JBG_EINVAL;
+ /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+ if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+ return JBG_EIMPL;
+ s->mx = s->buffer[16];
+ if (s->mx > 127)
+ return JBG_EINVAL;
+ s->my = s->buffer[17];
+#if 0
+ if (s->my > 0)
+ return JBG_EIMPL;
+#endif
+ s->order = s->buffer[18];
+ if (iindex[s->order & 7][0] < 0)
+ return JBG_EINVAL;
+ /* HITOLO and SEQ currently not yet implemented */
+ if (s->dl != s->d && (s->order & JBG_HITOLO || s->order & JBG_SEQ))
+ return JBG_EIMPL;
+ s->options = s->buffer[19];
+
+ /* calculate number of stripes that will be required */
+ s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+
+ /* some initialization */
+ s->ii[iindex[s->order & 7][STRIPE]] = 0;
+ s->ii[iindex[s->order & 7][LAYER]] = s->dl;
+ s->ii[iindex[s->order & 7][PLANE]] = 0;
+ if (s->dl == 0) {
+ s->s = (struct jbg_ardec_state **)
+ checked_malloc(s->planes, sizeof(struct jbg_ardec_state *));
+ s->tx = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->ty = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->reset = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->lntp = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->lhp[0] = (unsigned char **)
+ checked_malloc(s->planes, sizeof(unsigned char *));
+ s->lhp[1] = (unsigned char **)
+ checked_malloc(s->planes, sizeof(unsigned char *));
+ for (i = 0; i < s->planes; i++) {
+ s->s[i] = (struct jbg_ardec_state *)
+ checked_malloc(s->d - s->dl + 1, sizeof(struct jbg_ardec_state));
+ s->tx[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->ty[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->reset[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->lntp[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->lhp[ s->d & 1][i] = (unsigned char *)
+ checked_malloc(s->yd, jbg_ceil_half(s->xd, 3));
+ s->lhp[(s->d-1) & 1][i] = (unsigned char *)
+ checked_malloc(jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3));
+ }
+ } else {
+ for (i = 0; i < s->planes; i++) {
+ s->s[i] = (struct jbg_ardec_state *)
+ checked_realloc(s->s[i], s->d - s->dl + 1,
+ sizeof(struct jbg_ardec_state));
+ s->tx[i] = (int *) checked_realloc(s->tx[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->ty[i] = (int *) checked_realloc(s->ty[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->reset[i] = (int *) checked_realloc(s->reset[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->lntp[i] = (int *) checked_realloc(s->lntp[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->lhp[ s->d & 1][i] = (unsigned char *)
+ checked_realloc(s->lhp[ s->d & 1][i],
+ s->yd, jbg_ceil_half(s->xd, 3));
+ s->lhp[(s->d-1) & 1][i] = (unsigned char *)
+ checked_realloc(s->lhp[(s->d-1) & 1][i],
+ jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3));
+ }
+ }
+ for (i = 0; i < s->planes; i++)
+ for (j = 0; j <= s->d - s->dl; j++)
+ arith_decode_init(s->s[i] + j, 0);
+ if (s->dl == 0 || (s->options & JBG_DPON && !(s->options & JBG_DPPRIV)))
+ s->dppriv = jbg_dptable;
+ s->comment_skip = 0;
+ s->buf_len = 0;
+ s->x = 0;
+ s->i = 0;
+ s->pseudo = 1;
+ s->at_moves = 0;
+ }
+
+ /* read in DPTABLE */
+ if (s->bie_len < 20 + 1728 &&
+ (s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) ==
+ (JBG_DPON | JBG_DPPRIV)) {
+ assert(s->bie_len >= 20);
+ while (s->bie_len < 20 + 1728 && *cnt < len)
+ s->buffer[s->bie_len++ - 20] = data[(*cnt)++];
+ if (s->bie_len < 20 + 1728)
+ return JBG_EAGAIN;
+ if (!s->dppriv || s->dppriv == jbg_dptable)
+ s->dppriv = (char *) checked_malloc(1728, sizeof(char));
+ jbg_dppriv2int(s->dppriv, s->buffer);
+ }
+
+ /*
+ * BID processing loop
+ */
+
+ while (*cnt < len) {
+
+ /* process floating marker segments */
+
+ /* skip COMMENT contents */
+ if (s->comment_skip) {
+ if (s->comment_skip <= len - *cnt) {
+ *cnt += s->comment_skip;
+ s->comment_skip = 0;
+ } else {
+ s->comment_skip -= len - *cnt;
+ *cnt = len;
+ }
+ continue;
+ }
+
+ /* load complete marker segments into s->buffer for processing */
+ if (s->buf_len > 0) {
+ assert(s->buffer[0] == MARKER_ESC);
+ while (s->buf_len < 2 && *cnt < len)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+ if (s->buf_len < 2) continue;
+ switch (s->buffer[1]) {
+ case MARKER_COMMENT: required_length = 6; break;
+ case MARKER_ATMOVE: required_length = 8; break;
+ case MARKER_NEWLEN: required_length = 6; break;
+ case MARKER_ABORT:
+ case MARKER_SDNORM:
+ case MARKER_SDRST: required_length = 2; break;
+ case MARKER_STUFF:
+ /* forward stuffed 0xff to arithmetic decoder */
+ s->buf_len = 0;
+ decode_pscd(s, s->buffer, 2);
+ continue;
+ default:
+ return JBG_EMARKER;
+ }
+ while (s->buf_len < required_length && *cnt < len)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+ if (s->buf_len < required_length) continue;
+ /* now the buffer is filled with exactly one marker segment */
+ switch (s->buffer[1]) {
+ case MARKER_COMMENT:
+ s->comment_skip =
+ (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ break;
+ case MARKER_ATMOVE:
+ if (s->at_moves < JBG_ATMOVES_MAX) {
+ s->at_line[s->at_moves] =
+ (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ s->at_tx[s->at_moves] = (signed char) s->buffer[6];
+ s->at_ty[s->at_moves] = s->buffer[7];
+ if (s->at_tx[s->at_moves] < - (int) s->mx ||
+ s->at_tx[s->at_moves] > (int) s->mx ||
+ s->at_ty[s->at_moves] > (int) s->my ||
+ (s->at_ty[s->at_moves] == 0 && s->at_tx[s->at_moves] < 0))
+ return JBG_EINVAL;
+ if (s->at_ty[s->at_moves] != 0)
+ return JBG_EIMPL;
+ s->at_moves++;
+ } else
+ return JBG_EIMPL;
+ break;
+ case MARKER_NEWLEN:
+ y = (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ if (y > s->yd || !(s->options & JBG_VLENGTH))
+ return JBG_EINVAL;
+ s->yd = y;
+ /* calculate again number of stripes that will be required */
+ s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+ break;
+ case MARKER_ABORT:
+ return JBG_EABORT;
+
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+ /* decode final pixels based on trailing zero bytes */
+ decode_pscd(s, s->buffer, 2);
+
+ arith_decode_init(s->s[s->ii[iindex[s->order & 7][PLANE]]] +
+ s->ii[iindex[s->order & 7][LAYER]] - s->dl,
+ s->ii[iindex[s->order & 7][STRIPE]] != s->stripes - 1
+ && s->buffer[1] != MARKER_SDRST);
+
+ s->reset[s->ii[iindex[s->order & 7][PLANE]]]
+ [s->ii[iindex[s->order & 7][LAYER]] - s->dl] =
+ (s->buffer[1] == MARKER_SDRST);
+
+ /* prepare for next SDE */
+ s->x = 0;
+ s->i = 0;
+ s->pseudo = 1;
+ s->at_moves = 0;
+
+ /* increment layer/stripe/plane loop variables */
+ /* start and end value for each loop: */
+ is[iindex[s->order & 7][STRIPE]] = 0;
+ ie[iindex[s->order & 7][STRIPE]] = s->stripes - 1;
+ is[iindex[s->order & 7][LAYER]] = s->dl;
+ ie[iindex[s->order & 7][LAYER]] = s->d;
+ is[iindex[s->order & 7][PLANE]] = 0;
+ ie[iindex[s->order & 7][PLANE]] = s->planes - 1;
+ i = 2; /* index to innermost loop */
+ do {
+ j = 0; /* carry flag */
+ if (++s->ii[i] > ie[i]) {
+ /* handling overflow of loop variable */
+ j = 1;
+ if (i > 0)
+ s->ii[i] = is[i];
+ }
+ } while (--i >= 0 && j);
+
+ s->buf_len = 0;
+
+ /* check whether this have been all SDEs */
+ if (j) {
+#ifdef DEBUG
+ fprintf(stderr, "This was the final SDE in this BIE, "
+ "%d bytes left.\n", len - *cnt);
+#endif
+ s->bie_len = 0;
+ return JBG_EOK;
+ }
+
+ /* check whether we have to abort because of xmax/ymax */
+ if (iindex[s->order & 7][LAYER] == 0 && i < 0) {
+ /* LAYER is the outermost loop and we have just gone to next layer */
+ if (jbg_ceil_half(s->xd, s->d - s->ii[0]) > s->xmax ||
+ jbg_ceil_half(s->yd, s->d - s->ii[0]) > s->ymax) {
+ s->xmax = 4294967295UL;
+ s->ymax = 4294967295UL;
+ return JBG_EOK_INTR;
+ }
+ if (s->ii[0] > (unsigned long) s->dmax) {
+ s->dmax = 256;
+ return JBG_EOK_INTR;
+ }
+ }
+
+ break;
+ }
+ s->buf_len = 0;
+
+ } else if (data[*cnt] == MARKER_ESC)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+
+ else {
+
+ /* we have found PSCD bytes */
+ *cnt += decode_pscd(s, data + *cnt, len - *cnt);
+ if (*cnt < len && data[*cnt] != 0xff) {
+#ifdef DEBUG
+ fprintf(stderr, "PSCD was longer than expected, unread bytes "
+ "%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1],
+ data[*cnt+2], data[*cnt+3]);
+#endif
+ return JBG_EINVAL;
+ }
+
+ }
+ } /* of BID processing loop 'while (*cnt < len) ...' */
+
+ return JBG_EAGAIN;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to find out the width of the image.
+ */
+long jbg_dec_getwidth(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ else
+ return jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1));
+ }
+
+ return s->xd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to find out the height of the image.
+ */
+long jbg_dec_getheight(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ else
+ return jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1));
+ }
+
+ return s->yd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to get a pointer to the image.
+ */
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane)
+{
+ if (s->d < 0)
+ return NULL;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return NULL;
+ else
+ return s->lhp[(s->ii[0] - 1) & 1][plane];
+ }
+
+ return s->lhp[s->d & 1][plane];
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call
+ * this function in order to find out the size in bytes of one
+ * bitplane of the image.
+ */
+long jbg_dec_getsize(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ else
+ return
+ jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1) + 3) *
+ jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1));
+ }
+
+ return jbg_ceil_half(s->xd, 3) * s->yd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call
+ * this function in order to find out the size of the image that you
+ * can retrieve with jbg_merge_planes().
+ */
+long jbg_dec_getsize_merged(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ else
+ return
+ jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1)) *
+ jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1)) *
+ ((s->planes + 7) / 8);
+ }
+
+ return s->xd * s->yd * ((s->planes + 7) / 8);
+}
+
+
+/*
+ * The destructor function which releases any resources obtained by the
+ * other decoder functions.
+ */
+void jbg_dec_free(struct jbg_dec_state *s)
+{
+ int i;
+ extern char jbg_dptable[];
+
+ if (s->d < 0 || s->s == NULL)
+ return;
+ s->d = -2;
+
+ for (i = 0; i < s->planes; i++) {
+ checked_free(s->s[i]);
+ checked_free(s->tx[i]);
+ checked_free(s->ty[i]);
+ checked_free(s->reset[i]);
+ checked_free(s->lntp[i]);
+ checked_free(s->lhp[0][i]);
+ checked_free(s->lhp[1][i]);
+ }
+
+ checked_free(s->s);
+ checked_free(s->tx);
+ checked_free(s->ty);
+ checked_free(s->reset);
+ checked_free(s->lntp);
+ checked_free(s->lhp[0]);
+ checked_free(s->lhp[1]);
+ if (s->dppriv && s->dppriv != jbg_dptable)
+ checked_free(s->dppriv);
+
+ s->s = NULL;
+
+ return;
+}
+
+
+/*
+ * Split bigendian integer pixel field into separate bit planes. In the
+ * src array, every pixel is represented by a ((has_planes + 7) / 8) byte
+ * long word, most significant byte first. While has_planes describes
+ * the number of used bits per pixel in the source image, encode_plane
+ * is the number of most significant bits among those that we
+ * actually transfer to dest.
+ */
+void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+ int encode_planes,
+ const unsigned char *src, unsigned char **dest,
+ int use_graycode)
+{
+ unsigned long bpl = jbg_ceil_half(x, 3); /* bytes per line in dest plane */
+ unsigned long line, i;
+ unsigned k = 8;
+ int p;
+ unsigned prev; /* previous *src byte shifted by 8 bit to the left */
+ register int bits, msb = has_planes - 1;
+ int bitno;
+
+ /* sanity checks */
+ if (encode_planes > has_planes)
+ encode_planes = has_planes;
+ use_graycode = use_graycode != 0 && encode_planes > 1;
+
+ for (p = 0; p < encode_planes; p++)
+ memset(dest[p], 0, bpl * y);
+
+ for (line = 0; line < y; line++) { /* lines loop */
+ for (i = 0; i * 8 < x; i++) { /* dest bytes loop */
+ for (k = 0; k < 8 && i * 8 + k < x; k++) { /* pixel loop */
+ prev = 0;
+ for (p = 0; p < encode_planes; p++) { /* bit planes loop */
+ /* calculate which bit in *src do we want */
+ bitno = (msb - p) & 7;
+ /* put this bit with its left neighbor right adjusted into bits */
+ bits = (prev | *src) >> bitno;
+ /* go to next *src byte, but keep old */
+ if (bitno == 0)
+ prev = *src++ << 8;
+ /* make space for inserting new bit */
+ dest[p][bpl * line + i] <<= 1;
+ /* insert bit, if requested apply Gray encoding */
+ dest[p][bpl * line + i] |= (bits ^ (use_graycode & (bits>>1))) & 1;
+ /*
+ * Theorem: Let b(n),...,b(1),b(0) be the digits of a
+ * binary word and let g(n),...,g(1),g(0) be the digits of the
+ * corresponding Gray code word, then g(i) = b(i) xor b(i+1).
+ */
+ }
+ /* skip unused *src bytes */
+ for (;p < has_planes; p++)
+ if (((msb - p) & 7) == 0)
+ src++;
+ }
+ }
+ for (p = 0; p < encode_planes; p++) /* right padding loop */
+ dest[p][bpl * (line + 1) - 1] <<= 8 - k;
+ }
+
+ return;
+}
+
+/*
+ * Merge the separate bit planes decoded by the JBIG decoder into an
+ * integer pixel field. This is essentially the counterpart to
+ * jbg_split_planes().
+ */
+void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file), void *file)
+{
+#define BUFLEN 4096
+ int bpp;
+ unsigned long bpl, line, i;
+ unsigned k = 8;
+ int p;
+ unsigned char buf[BUFLEN];
+ unsigned char *bp = buf;
+ unsigned char **src;
+ unsigned long x, y;
+ unsigned v;
+
+ /* sanity check */
+ use_graycode = use_graycode != 0;
+
+ x = jbg_dec_getwidth(s);
+ y = jbg_dec_getheight(s);
+ if (x <= 0 || y <= 0)
+ return;
+ bpp = (s->planes + 7) / 8; /* bytes per pixel in dest image */
+ bpl = jbg_ceil_half(x, 3); /* bytes per line in src plane */
+
+ if (iindex[s->order & 7][LAYER] == 0)
+ if (s->ii[0] < 1)
+ return;
+ else
+ src = s->lhp[(s->ii[0] - 1) & 1];
+ else
+ src = s->lhp[s->d & 1];
+
+ for (line = 0; line < y; line++) { /* lines loop */
+ for (i = 0; i * 8 < x; i++) { /* src bytes loop */
+ for (k = 0; k < 8 && i * 8 + k < x; k++) { /* pixel loop */
+ v = 0;
+ for (p = 0; p < s->planes;) { /* dest bytes loop */
+ do {
+ v = (v << 1) |
+ (((src[p][bpl * line + i] >> (7 - k)) & 1) ^
+ (use_graycode & v));
+ } while ((s->planes - ++p) & 7);
+ *bp++ = v;
+ if (bp - buf == BUFLEN) {
+ data_out(buf, BUFLEN, file);
+ bp = buf;
+ }
+ }
+ }
+ }
+ }
+
+ if (bp - buf > 0)
+ data_out(buf, bp - buf, file);
+
+ return;
+}
+
+
+/*
+ * Given a pointer p to the first byte of either a marker segment or a
+ * PSCD, as well as the length len of the remaining data, return
+ * either the pointer to the first byte of the next marker segment or
+ * PSCD, or p+len if this was the last one, or NULL if some error was
+ * encountered.
+ */
+unsigned char *jbg_next_pscdms(unsigned char *p, size_t len)
+{
+ unsigned char *pp;
+ unsigned long l;
+
+ if (len < 2)
+ return NULL;
+
+ if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) {
+ do {
+ while (p[0] == MARKER_ESC && p[1] == MARKER_STUFF) {
+ p += 2;
+ len -= 2;
+ if (len < 2) return NULL;
+ }
+ pp = (unsigned char *) memchr(p, MARKER_ESC, len - 1);
+ if (!pp) return NULL;
+ l = pp - p;
+ assert(l < len);
+ p += l;
+ len -= l;
+ } while (p[1] == MARKER_STUFF);
+ } else {
+ switch (p[1]) {
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+ case MARKER_ABORT:
+ return p + 2;
+ case MARKER_NEWLEN:
+ if (len < 6) return NULL;
+ return p + 6;
+ case MARKER_ATMOVE:
+ if (len < 8) return NULL;
+ return p + 8;
+ case MARKER_COMMENT:
+ if (len < 6) return NULL;
+ l = (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]);
+ if (len - 6 < l) return NULL;
+ return p + 6 + l;
+ default:
+ return NULL;
+ }
+ }
+
+ return p;
+}
+
+
+/*
+ * Scan a complete BIE for a NEWLEN marker segment, then read the new
+ * YD value found in it and use it to overwrite the one in the BIE
+ * header. Use this procedure if a BIE initially declares an
+ * unreasonably high provisional YD value (e.g., 0xffffffff) or
+ * depends on the fact that section 6.2.6.2 of ITU-T T.82 says that a
+ * NEWLEN marker segment "could refer to a line in the immediately
+ * preceding stripe due to an unexpected termination of the image or
+ * the use of only such stripe". ITU-T.85 explicitely suggests the
+ * use of this for fax machines that start transmission before having
+ * encountered the end of the page. None of this is necessary for
+ * BIEs produced by JBIG-KIT, which normally does not use NEWLEN.
+ */
+int jbg_newlen(unsigned char *bie, size_t len)
+{
+ unsigned char *p = bie + 20;
+ int i;
+
+ if (len < 20)
+ return JBG_EAGAIN;
+ if ((bie[19] & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST))
+ == (JBG_DPON | JBG_DPPRIV))
+ p += 1728; /* skip DPTABLE */
+ if (p >= bie + len)
+ return JBG_EAGAIN;
+
+ while ((p = jbg_next_pscdms(p, len - (p - bie)))) {
+ if (p == bie + len)
+ return JBG_EOK;
+ else if (p[0] == MARKER_ESC)
+ switch (p[1]) {
+ case MARKER_NEWLEN:
+ /* overwrite YD in BIH with YD from NEWLEN */
+ for (i = 0; i < 4; i++) {
+ bie[8+i] = p[2+i];
+ }
+ return JBG_EOK;
+ case MARKER_ABORT:
+ return JBG_EABORT;
+ }
+ }
+ return JBG_EINVAL;
+}
diff --git a/kernel/kls_jbig/libjbig/jbig.h b/kernel/kls_jbig/libjbig/jbig.h
new file mode 100644
index 0000000..1129ac0
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/jbig.h
@@ -0,0 +1,270 @@
+/*
+ * Header file for the portable free JBIG compression library
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ * $Id: jbig.h,v 1.17 2004-06-11 15:18:21+01 mgk25 Exp $
+ */
+
+#ifndef JBG_H
+#define JBG_H
+
+#include <stddef.h>
+
+/*
+ * JBIG-KIT version number
+ */
+
+#define JBG_VERSION "1.6"
+
+/*
+ * Buffer block for SDEs which are temporarily stored by encoder
+ */
+
+#define JBG_BUFSIZE 4000
+
+struct jbg_buf {
+ unsigned char d[JBG_BUFSIZE]; /* one block of a buffer list */
+ int len; /* length of the data in this block */
+ struct jbg_buf *next; /* pointer to next block */
+ struct jbg_buf *previous; /* pointer to previous block *
+ * (unused in freelist) */
+ struct jbg_buf *last; /* only used in list head: final block of list */
+ struct jbg_buf **free_list; /* pointer to pointer to head of free list */
+};
+
+/*
+ * Maximum number of ATMOVEs per stripe that decoder can handle
+ */
+
+#define JBG_ATMOVES_MAX 64
+
+/*
+ * Option and order flags
+ */
+
+#define JBG_HITOLO 0x08
+#define JBG_SEQ 0x04
+#define JBG_ILEAVE 0x02
+#define JBG_SMID 0x01
+
+#define JBG_LRLTWO 0x40
+#define JBG_VLENGTH 0x20
+#define JBG_TPDON 0x10
+#define JBG_TPBON 0x08
+#define JBG_DPON 0x04
+#define JBG_DPPRIV 0x02
+#define JBG_DPLAST 0x01
+
+#define JBG_DELAY_AT 0x100 /* delay ATMOVE until the first line of the next
+ * stripe. Option available for compatibility
+ * with conformance test example in clause 7.2.*/
+
+
+/*
+ * Possible error code return values
+ */
+
+#define JBG_EOK 0
+#define JBG_EOK_INTR 1
+#define JBG_EAGAIN 2
+#define JBG_ENOMEM 3
+#define JBG_EABORT 4
+#define JBG_EMARKER 5
+#define JBG_ENOCONT 6
+#define JBG_EINVAL 7
+#define JBG_EIMPL 8
+
+/*
+ * Language code for error message strings (based on ISO 639 2-letter
+ * standard language name abbreviations).
+ */
+
+#define JBG_EN 0 /* English */
+#define JBG_DE_8859_1 1 /* German in ISO Latin 1 character set */
+#define JBG_DE_UTF_8 2 /* German in Unicode UTF-8 encoding */
+
+/*
+ * Status description of an arithmetic encoder
+ */
+
+struct jbg_arenc_state {
+ unsigned char st[4096]; /* probability status for contexts, MSB = MPS */
+ unsigned long c; /* C register, base of coding intervall, *
+ * layout as in Table 23 */
+ unsigned long a; /* A register, normalized size of coding intervall */
+ long sc; /* counter for buffered 0xff values which might overflow */
+ int ct; /* bit shift counter, determines when next byte will be written */
+ int buffer; /* buffer for most recent output byte != 0xff */
+ void (*byte_out)(int, void *); /* function which receives all PSCD bytes */
+ void *file; /* parameter passed to byte_out */
+};
+
+
+/*
+ * Status description of an arithmetic decoder
+ */
+
+enum jbg_ardec_result {
+ JBG_OK, /* symbol has been successfully decoded */
+ JBG_READY, /* no more bytes of this PSCD required, marker *
+ * encountered, probably more symbols available */
+ JBG_MORE, /* more PSCD data bytes required to decode a symbol */
+ JBG_MARKER /* more PSCD data bytes required, ignored final 0xff byte */
+};
+
+struct jbg_ardec_state {
+ unsigned char st[4096]; /* probability status for contexts, MSB = MPS */
+ unsigned long c; /* C register, base of coding intervall, *
+ * layout as in Table 25 */
+ unsigned long a; /* A register, normalized size of coding intervall */
+ int ct; /* bit shift counter, determines when next byte will be read */
+ unsigned char *pscd_ptr; /* pointer to next PSCD data byte */
+ unsigned char *pscd_end; /* pointer to byte after PSCD */
+ enum jbg_ardec_result result; /* result of previous decode call */
+ int startup; /* controls initial fill of s->c */
+};
+
+/*
+ * Status of a JBIG encoder
+ */
+
+struct jbg_enc_state {
+ int d; /* resolution layer of the input image */
+ unsigned long xd, yd; /* size of the input image (resolution layer d) */
+ unsigned long yd1; /* BIH announced height of image, use yd1 != yd to
+ emulate T.85-style NEWLEN height updates for tests */
+ int planes; /* number of different bitmap planes */
+ int dl; /* lowest resolution layer in the next BIE */
+ int dh; /* highest resolution layer in the next BIE */
+ unsigned long l0; /* number of lines per stripe at lowest *
+ * resolution layer 0 */
+ unsigned long stripes; /* number of stripes required (determ. by l0) */
+ unsigned char **lhp[2]; /* pointers to lower/higher resolution images */
+ int *highres; /* index [plane] of highres image in lhp[] */
+ int order; /* SDE ordering parameters */
+ int options; /* encoding parameters */
+ unsigned mx, my; /* maximum ATMOVE window size */
+ int *tx; /* array [plane] with x-offset of adaptive template pixel */
+ char *dppriv; /* optional private deterministic prediction table */
+ char *res_tab; /* table for the resolution reduction algorithm */
+ struct jbg_buf ****sde; /* array [stripe][layer][plane] pointers to *
+ * buffers for stored SDEs */
+ struct jbg_arenc_state *s; /* array [planes] for arithm. encoder status */
+ struct jbg_buf *free_list; /* list of currently unused SDE block buffers */
+ void (*data_out)(unsigned char *start, size_t len, void *file);
+ /* data write callback */
+ void *file; /* parameter passed to data_out() */
+ char *tp; /* buffer for temp. values used by diff. typical prediction */
+};
+
+
+/*
+ * Status of a JBIG decoder
+ */
+
+struct jbg_dec_state {
+ /* data from BIH */
+ int d; /* resolution layer of the full image */
+ int dl; /* first resolution layer in this BIE */
+ unsigned long xd, yd; /* size of the full image (resolution layer d) */
+ int planes; /* number of different bitmap planes */
+ unsigned long l0; /* number of lines per stripe at lowest *
+ * resolution layer 0 */
+ unsigned long stripes; /* number of stripes required (determ. by l0) */
+ int order; /* SDE ordering parameters */
+ int options; /* encoding parameters */
+ int mx, my; /* maximum ATMOVE window size */
+ char *dppriv; /* optional private deterministic prediction table */
+
+ /* loop variables */
+ unsigned long ii[3]; /* current stripe, layer, plane (outer loop first) */
+
+ /*
+ * Pointers to array [planes] of lower/higher resolution images.
+ * lhp[d & 1] contains image of layer d.
+ */
+ unsigned char **lhp[2];
+
+ /* status information */
+ int **tx, **ty; /* array [plane][layer-dl] with x,y-offset of AT pixel */
+ struct jbg_ardec_state **s; /* array [plane][layer-dl] for arithmetic *
+ * decoder status */
+ int **reset; /* array [plane][layer-dl] remembers if previous stripe *
+ * in that plane/resolution ended with SDRST. */
+ unsigned long bie_len; /* number of bytes read so far */
+ unsigned char buffer[20]; /* used to store BIH or marker segments fragm. */
+ int buf_len; /* number of bytes in buffer */
+ unsigned long comment_skip; /* remaining bytes of a COMMENT segment */
+ unsigned long x; /* x position of next pixel in current SDE */
+ unsigned long i; /* line in current SDE (first line of each stripe is 0) */
+ int at_moves; /* number of AT moves in the current stripe */
+ unsigned long at_line[JBG_ATMOVES_MAX]; /* lines at which an *
+ * AT move will happen */
+ int at_tx[JBG_ATMOVES_MAX], at_ty[JBG_ATMOVES_MAX]; /* ATMOVE offsets in *
+ * current stripe */
+ unsigned long line_h1, line_h2, line_h3; /* variables of decode_pscd */
+ unsigned long line_l1, line_l2, line_l3;
+ int pseudo; /* flag for TPBON/TPDON: next pixel is pseudo pixel */
+ int **lntp; /* flag [plane][layer-dl] for TP: line is not typical */
+
+ unsigned long xmax, ymax; /* if possible abort before image gets *
+ * larger than this size */
+ int dmax; /* abort after this layer */
+};
+
+
+/* some macros (too trivial for a function) */
+
+#define jbg_dec_getplanes(s) ((s)->planes)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* function prototypes */
+
+void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+ int planes, unsigned char **p,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file);
+int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth,
+ unsigned long mheight);
+void jbg_enc_layers(struct jbg_enc_state *s, int d);
+int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh);
+void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+ unsigned long l0, int mx, int my);
+void jbg_enc_out(struct jbg_enc_state *s);
+void jbg_enc_free(struct jbg_enc_state *s);
+
+void jbg_dec_init(struct jbg_dec_state *s);
+void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+ unsigned long ymax);
+int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt);
+long jbg_dec_getwidth(const struct jbg_dec_state *s);
+long jbg_dec_getheight(const struct jbg_dec_state *s);
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane);
+long jbg_dec_getsize(const struct jbg_dec_state *s);
+void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file), void *file);
+long jbg_dec_getsize_merged(const struct jbg_dec_state *s);
+void jbg_dec_free(struct jbg_dec_state *s);
+
+const char *jbg_strerror(int errnum, int language);
+void jbg_int2dppriv(unsigned char *dptable, const char *internal);
+void jbg_dppriv2int(char *internal, const unsigned char *dptable);
+unsigned long jbg_ceil_half(unsigned long x, int n);
+void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+ int encode_planes,
+ const unsigned char *src, unsigned char **dest,
+ int use_graycode);
+int jbg_newlen(unsigned char *bie, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JBG_H */
diff --git a/kernel/kls_jbig/libjbig/jbig_tab.c b/kernel/kls_jbig/libjbig/jbig_tab.c
new file mode 100644
index 0000000..5518350
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/jbig_tab.c
@@ -0,0 +1,428 @@
+/*
+ * Probability estimation tables for the arithmetic encoder/decoder
+ * given by ITU T.82 Table 24.
+ *
+ * $Id: jbig_tab.c,v 1.6 1998-04-05 18:36:19+01 mgk25 Rel $
+ */
+
+short jbg_lsz[113] = {
+ 0x5a1d, 0x2586, 0x1114, 0x080b, 0x03d8, 0x01da, 0x00e5, 0x006f,
+ 0x0036, 0x001a, 0x000d, 0x0006, 0x0003, 0x0001, 0x5a7f, 0x3f25,
+ 0x2cf2, 0x207c, 0x17b9, 0x1182, 0x0cef, 0x09a1, 0x072f, 0x055c,
+ 0x0406, 0x0303, 0x0240, 0x01b1, 0x0144, 0x00f5, 0x00b7, 0x008a,
+ 0x0068, 0x004e, 0x003b, 0x002c, 0x5ae1, 0x484c, 0x3a0d, 0x2ef1,
+ 0x261f, 0x1f33, 0x19a8, 0x1518, 0x1177, 0x0e74, 0x0bfb, 0x09f8,
+ 0x0861, 0x0706, 0x05cd, 0x04de, 0x040f, 0x0363, 0x02d4, 0x025c,
+ 0x01f8, 0x01a4, 0x0160, 0x0125, 0x00f6, 0x00cb, 0x00ab, 0x008f,
+ 0x5b12, 0x4d04, 0x412c, 0x37d8, 0x2fe8, 0x293c, 0x2379, 0x1edf,
+ 0x1aa9, 0x174e, 0x1424, 0x119c, 0x0f6b, 0x0d51, 0x0bb6, 0x0a40,
+ 0x5832, 0x4d1c, 0x438e, 0x3bdd, 0x34ee, 0x2eae, 0x299a, 0x2516,
+ 0x5570, 0x4ca9, 0x44d9, 0x3e22, 0x3824, 0x32b4, 0x2e17, 0x56a8,
+ 0x4f46, 0x47e5, 0x41cf, 0x3c3d, 0x375e, 0x5231, 0x4c0f, 0x4639,
+ 0x415e, 0x5627, 0x50e7, 0x4b85, 0x5597, 0x504f, 0x5a10, 0x5522,
+ 0x59eb
+};
+
+unsigned char jbg_nmps[113] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 13, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 9, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 32,
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 48,
+ 81, 82, 83, 84, 85, 86, 87, 71,
+ 89, 90, 91, 92, 93, 94, 86, 96,
+ 97, 98, 99, 100, 93, 102, 103, 104,
+ 99, 106, 107, 103, 109, 107, 111, 109,
+ 111
+};
+
+/*
+ * least significant 7 bits (mask 0x7f) of jbg_nlps[] contain NLPS value,
+ * most significant bit (mask 0x80) contains SWTCH bit
+ */
+unsigned char jbg_nlps[113] = {
+ 129, 14, 16, 18, 20, 23, 25, 28,
+ 30, 33, 35, 9, 10, 12, 143, 36,
+ 38, 39, 40, 42, 43, 45, 46, 48,
+ 49, 51, 52, 54, 56, 57, 59, 60,
+ 62, 63, 32, 33, 165, 64, 65, 67,
+ 68, 69, 70, 72, 73, 74, 75, 77,
+ 78, 79, 48, 50, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 61, 61,
+ 193, 80, 81, 82, 83, 84, 86, 87,
+ 87, 72, 72, 74, 74, 75, 77, 77,
+ 208, 88, 89, 90, 91, 92, 93, 86,
+ 216, 95, 96, 97, 99, 99, 93, 223,
+ 101, 102, 103, 104, 99, 105, 106, 107,
+ 103, 233, 108, 109, 110, 111, 238, 112,
+ 240
+};
+
+/*
+ * Resolution reduction table given by ITU-T T.82 Table 17
+ */
+
+char jbg_resred[4096] = {
+ 0,0,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,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,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,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,
+ 0,0,1,1,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,
+ 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,1,1,1,1,
+ 0,0,1,1,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,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 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,
+ 0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,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,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,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,1,1,0,1,1,
+ 0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,0,1,1,0,1,1,0,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,0,0,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 1,1,1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,0,1,0,0,1,0,0,1,1,0,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,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,
+ 1,0,0,1,0,0,1,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,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,
+ 0,0,1,0,1,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,
+ 0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,1,0,1,1,0,1,1,0,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,0,0,0,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,
+ 0,0,1,0,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,
+ 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,
+ 0,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,
+ 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,1,0,1,1,1,
+ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,1,0,0,1,1,1,0,1,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,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,1,1,1,1,
+ 0,0,0,1,0,0,1,0,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,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,1,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,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,1,1,1,1,1,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,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,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1,
+ 0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,1,0,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,1,0,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,
+ 0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,0,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,
+ 1,1,1,0,1,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1,
+ 0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,1,0,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,0,0,1,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,1,1,0,
+ 0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,0,1,0,1,1,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,
+ 0,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,
+ 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,
+ 0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,
+ 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,1,0,1,1,1,0,1,1,1
+};
+
+/*
+ * Deterministic prediction tables given by ITU-T T.82 tables
+ * 19 to 22. The table below is organized differently, the
+ * index bits are permutated for higher efficiency.
+ */
+
+char jbg_dptable[256 + 512 + 2048 + 4096] = {
+ /* phase 0: offset=0 */
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,
+ 0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,0,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,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,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,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,
+ /* phase 1: offset=256 */
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,2,
+ 0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,0,0,2,2,2,2,2,0,0,2,2,2,2,2,
+ 0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,
+ 1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,1,2,2,2,2,2,0,2,2,2,2,2,2,
+ 2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,0,2,0,2,2,2,2,2,0,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+ 2,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,1,
+ 0,2,0,2,2,1,2,1,2,2,2,2,1,1,1,1,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,1,
+ 2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,0,0,2,2,2,2,2,
+ 2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,
+ /* phase 2: offset=768 */
+ 2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 0,2,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,2,2,2,2,2,1,1,1,
+ 2,0,2,2,2,1,2,1,0,2,2,2,1,2,1,2,2,2,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+ 0,2,0,0,1,1,1,1,2,2,2,2,1,1,1,1,0,2,0,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,1,2,1,2,2,2,0,2,2,1,2,1,0,2,0,2,1,1,1,1,
+ 2,0,0,2,2,2,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,2,1,2,2,0,2,1,1,2,1,
+ 2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 0,0,0,0,2,2,2,2,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,2,1,0,2,2,2,1,1,1,1,2,0,2,2,2,2,2,2,0,2,0,2,2,1,2,1,
+ 2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1,
+ 2,2,2,0,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,1,2,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,0,2,0,2,2,2,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,
+ 2,2,2,1,2,2,2,2,2,2,1,2,0,0,0,0,2,2,0,2,2,1,2,2,2,2,2,2,1,1,1,1,
+ 2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,0,0,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1,
+ 0,2,0,2,2,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,
+ 2,0,2,0,2,1,2,1,0,2,0,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,1,2,
+ 2,2,2,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,1,2,2,2,2,2,2,0,1,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1,
+ 2,0,2,0,2,1,2,2,0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,
+ 2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1,
+ 2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,0,0,2,2,2,1,2,2,2,
+ 0,0,2,0,2,2,2,2,0,2,0,2,2,0,2,0,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+ 2,2,0,0,2,2,2,2,2,2,2,0,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,1,1,1,1,2,2,2,2,1,1,1,1,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,1,0,1,2,2,2,2,1,0,2,2,2,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,2,2,0,2,2,1,2,2,
+ 0,2,0,0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,1,
+ 2,2,0,2,2,1,2,2,2,2,2,2,1,2,2,2,2,0,2,2,2,2,2,2,0,2,0,2,1,2,1,1,
+ 2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,2,2,2,2,1,1,2,2,2,2,2,1,2,2,2,
+ 2,0,2,2,2,1,2,1,0,2,2,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,
+ 0,2,0,0,2,2,2,2,1,2,2,2,2,2,2,0,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,
+ 0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,0,2,2,
+ 0,0,0,2,2,1,1,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,1,2,2,2,2,1,2,1,2,
+ 0,0,0,0,2,2,2,2,2,2,0,2,2,1,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,2,2,2,
+ 2,0,2,0,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,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,1,2,2,2,2,2,0,2,2,1,2,2,0,0,0,2,2,2,2,2,1,2,2,0,2,2,2,1,2,1,2,
+ 2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,0,2,0,0,2,2,2,2,2,2,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+ 1,2,0,2,2,1,2,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,2,2,0,2,2,1,1,1,1,
+ 0,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,1,
+ 2,2,0,0,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,
+ 2,2,2,0,2,2,2,2,2,2,2,0,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,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,
+ 2,0,2,0,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,0,2,0,2,2,2,1,2,
+ 2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1,
+ 2,2,2,2,2,1,2,1,0,2,0,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,1,
+ 2,0,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,
+ 2,0,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,0,2,0,2,2,2,2,0,0,0,2,2,2,2,1,
+ 2,0,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,
+ /* phase 3: offset=2816 */
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,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,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,1,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,
+ 2,2,2,1,2,2,2,0,1,1,1,1,0,0,0,0,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,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,1,2,1,2,0,2,0,2,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,0,2,0,2,1,2,1,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,
+ 2,0,2,2,2,1,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,0,1,1,2,1,
+ 2,2,2,0,2,2,2,1,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,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,0,2,2,2,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,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+ 2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,1,1,1,2,0,0,0,
+ 2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1,
+ 2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,2,0,1,1,2,1,
+ 2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1,
+ 2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+ 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,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,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,
+ 2,0,2,2,2,1,2,2,0,0,2,0,1,1,2,1,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,1,0,2,2,0,1,2,
+ 2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,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,0,2,2,2,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,0,0,2,1,1,1,2,0,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,1,2,1,2,0,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,2,2,0,2,2,2,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,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,2,2,0,0,2,2,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,0,2,2,2,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,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1,
+ 2,2,2,0,2,2,2,1,0,2,2,2,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,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,0,2,2,2,1,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,2,0,2,2,2,1,2,2,0,2,1,2,1,2,0,2,
+ 2,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,
+ 0,0,2,0,1,1,2,1,0,0,1,0,1,1,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,0,2,2,1,1,2,2,2,0,2,2,2,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,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,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,1,2,2,2,0,2,1,2,1,2,0,2,0,
+ 2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,
+ 2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,1,2,1,2,0,2,0,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,1,1,1,2,0,0,0,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+ 2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1,
+ 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,1,0,0,1,0,1,1,
+ 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,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,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,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,
+ 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,1,2,2,2,0,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,0,1,2,2,1,0,2,0,2,2,2,1,2,2,2,
+ 2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,
+ 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,1,0,1,2,0,1,0,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,1,2,2,2,0,2,2,1,1,2,2,0,0,2,2,
+ 0,2,2,2,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,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,
+ 2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,
+ 0,0,0,0,1,1,1,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,0,2,2,2,1,2,
+ 2,0,2,0,2,1,2,1,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,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,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,1,2,2,2,0,1,1,2,1,0,0,2,0,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,
+ 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,
+ 0,2,0,0,1,2,1,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,1,1,1,2,0,0,2,2,2,1,2,2,2,
+ 2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+ 0,0,2,2,1,1,2,2,0,2,1,2,1,2,0,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+ 2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,0,0,2,2,1,1,2,2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,1,
+ 2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+ 2,2,2,0,2,2,2,1,2,2,2,0,2,2,2,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,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,
+ 2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,
+ 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,
+ 2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,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,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,2,1,2,0,2,0,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,1,2,1,2,0,2,0,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,1,2,1,2,0,2,0,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,
+ 2,0,2,1,2,1,2,0,0,2,1,2,1,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,2,2,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,1,2,1,2,0,2,0,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,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,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+};
diff --git a/kernel/kls_jpeg/Makefile.am b/kernel/kls_jpeg/Makefile.am
new file mode 100644
index 0000000..7717e5e
--- /dev/null
+++ b/kernel/kls_jpeg/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_jpeg.la
+
+libkls_jpeg_la_SOURCES = fmt_codec_jpeg.cpp fmt_codec_jpeg_defs.h
+
+libkls_jpeg_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_jpeg_la_LIBADD = ${SQ_LOCAL_RPATH} -ljpeg \ No newline at end of file
diff --git a/kernel/kls_jpeg/fmt_codec_jpeg.cpp b/kernel/kls_jpeg/fmt_codec_jpeg.cpp
new file mode 100644
index 0000000..60fe8e8
--- /dev/null
+++ b/kernel/kls_jpeg/fmt_codec_jpeg.cpp
@@ -0,0 +1,308 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <csetjmp>
+#include <iostream>
+#include <cstdio>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_jpeg_defs.h"
+#include "fmt_codec_jpeg.h"
+
+#include "../xpm/codec_jpeg.xpm"
+
+/*
+ *
+ * JPEG (Joint Photographic Experts Group) refers to a
+ * standards organization, a method of file compression, and sometimes a
+ * file format. In fact, the JPEG specification
+ * itself does not define a common file interchange
+ * format to store and transport JPEG data between
+ * computer platforms and operating systems. The JPEG
+ * File Interchange Format (JFIF) is a development of
+ * C-Cube Microsystems for the purpose of storing
+ * JPEG-encoded data. JFIF is
+ * designed to allow files containing JPEG-encoded
+ * data streams to be exchanged between otherwise incompatible systems
+ * and applications.
+ *
+ */
+
+METHODDEF(void) my_error_exit(j_common_ptr cinfo)
+{
+ my_error_ptr myerr;
+
+ myerr = (my_error_ptr) cinfo->err;
+
+ (*cinfo->err->output_message) (cinfo);
+
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "1.3.4.1";
+ o->name = "JPEG compressed";
+ o->filter = "*.jpg *.jpeg *.jpe ";
+ o->config = "";
+ o->mime = "\x00FF\x00D8\x00FF";
+ o->mimetype = "image/jpeg";
+ o->pixmap = codec_jpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ zerror = false;
+
+ fptr = fopen(file.c_str(), "rb");
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = my_error_exit;
+
+ if(setjmp(jerr.setjmp_buffer))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, fptr);
+ jpeg_save_markers(&cinfo, JPEG_COM, 0xffff);
+ jpeg_read_header(&cinfo, TRUE);
+
+ if(cinfo.jpeg_color_space == JCS_GRAYSCALE)
+ {
+ cinfo.out_color_space = JCS_RGB;
+ cinfo.desired_number_of_colors = 256;
+ cinfo.quantize_colors = FALSE;
+ cinfo.two_pass_quantize = FALSE;
+ }
+
+ jpeg_start_decompress(&cinfo);
+
+ image.w = cinfo.output_width;
+ image.h = cinfo.output_height;
+
+ buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, cinfo.output_width * cinfo.output_components, 1);
+
+ std::string type;
+
+ switch(cinfo.jpeg_color_space)
+ {
+ case JCS_GRAYSCALE: type = "Grayscale"; image.bpp = 8; break;
+ case JCS_RGB: type = "RGB"; image.bpp = 24; break;
+ case JCS_YCbCr: type = "YUV"; image.bpp = 24; break;
+ case JCS_CMYK: type = "CMYK"; image.bpp = 32; break;
+ case JCS_YCCK: type = "YCCK"; image.bpp = 32; break;
+
+ default:
+ type = "Unknown";
+ }
+
+ image.compression = "JPEG";
+ image.colorspace = type;
+
+ jpeg_saved_marker_ptr it = cinfo.marker_list;
+
+ while(it)
+ {
+ if(it->marker == JPEG_COM)
+ {
+ fmt_metaentry mt;
+
+ mt.group = "Comment";
+ s8 data[it->data_length+1];
+ memcpy(data, it->data, it->data_length);
+ data[it->data_length] = '\0';
+ mt.data = data;
+
+ addmeta(mt);
+
+ break;
+ }
+
+ it = it->next;
+ }
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ if(zerror || setjmp(jerr.setjmp_buffer))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ (void)jpeg_read_scanlines(&cinfo, buffer, 1);
+
+ for(s32 i = 0;i < im->w;i++)
+ memcpy(scan+i, buffer[0] + i*3, 3);
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ jpeg_abort_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionInternal;
+ opt->compression_min = 0;
+ opt->compression_max = 100;
+ opt->compression_def = 25;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ m_fptr = fopen(file.c_str(), "wb");
+
+ if(!m_fptr)
+ return SQE_W_NOFILE;
+
+ m_cinfo.err = jpeg_std_error(&m_jerr);
+
+ jpeg_create_compress(&m_cinfo);
+
+ jpeg_stdio_dest(&m_cinfo, m_fptr);
+
+ m_cinfo.image_width = image.w;
+ m_cinfo.image_height = image.h;
+ m_cinfo.input_components = 3;
+ m_cinfo.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults(&m_cinfo);
+
+ jpeg_set_quality(&m_cinfo, 100-opt.compression_level, true);
+
+ jpeg_start_compress(&m_cinfo, true);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ RGB sr[writeimage.w];
+
+ for(s32 s = 0;s < writeimage.w;s++)
+ {
+ memcpy(sr+s, scan+s, sizeof(RGB));
+ }
+
+ row_pointer = (JSAMPLE *)sr;
+
+ (void)jpeg_write_scanlines(&m_cinfo, &row_pointer, 1);
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ jpeg_finish_compress(&m_cinfo);
+
+ fclose(m_fptr);
+
+ jpeg_destroy_compress(&m_cinfo);
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("jpeg");
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_jpeg/fmt_codec_jpeg_defs.h b/kernel/kls_jpeg/fmt_codec_jpeg_defs.h
new file mode 100644
index 0000000..89f1edc
--- /dev/null
+++ b/kernel/kls_jpeg/fmt_codec_jpeg_defs.h
@@ -0,0 +1,42 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_jpg
+#define KSQUIRREL_READ_IMAGE_jpg
+
+// thanks Trolltech's QT
+extern "C" {
+#define XMD_H // shut JPEGlib up
+#include <jpeglib.h>
+#ifdef const
+# undef const // remove crazy C hackery in jconfig.h
+#endif
+}
+
+struct my_error_mgr
+{
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+};
+
+typedef struct my_error_mgr * my_error_ptr;
+
+#endif
diff --git a/kernel/kls_jpeg2000/Makefile.am b/kernel/kls_jpeg2000/Makefile.am
new file mode 100644
index 0000000..7fc2b3d
--- /dev/null
+++ b/kernel/kls_jpeg2000/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_jpeg2000.la
+
+libkls_jpeg2000_la_SOURCES = fmt_codec_jpeg2000.cpp fmt_codec_jpeg2000_defs.h
+
+libkls_jpeg2000_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_jpeg2000_la_LIBADD = ${SQ_LOCAL_RPATH} -ljasper \ No newline at end of file
diff --git a/kernel/kls_jpeg2000/fmt_codec_jpeg2000.cpp b/kernel/kls_jpeg2000/fmt_codec_jpeg2000.cpp
new file mode 100644
index 0000000..c4fecf0
--- /dev/null
+++ b/kernel/kls_jpeg2000/fmt_codec_jpeg2000.cpp
@@ -0,0 +1,277 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#undef PACKAGE
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef VERSION
+
+#include <jasper/jasper.h>
+
+#include "fmt_codec_jpeg2000_defs.h"
+#include "fmt_codec_jpeg2000.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_jpeg2000.xpm"
+
+/*
+ *
+ * JPEG 2000 standard supports lossy and lossless compression of
+ * single-component (e.g., grayscale) and multicomponent (e.g., color)
+ * imagery.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{
+ jas_init();
+}
+
+fmt_codec::~fmt_codec()
+{
+ jas_cleanup();
+}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.4.0";
+ o->name = "JPEG 2000";
+ o->filter = "*.jp2 *.j2k ";
+
+ // mime is "....\152\120\040\040",
+ // but some jp2 files don't have this mime header (why ?)
+ // => o->mime is empty
+ o->mime = "";
+ o->mimetype = "image/jp2";
+ o->config = "";
+ o->pixmap = codec_jpeg2000;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ gs.image = 0;
+ gs.altimage = 0;
+ gs.data[0] = 0;
+ gs.data[1] = 0;
+ gs.data[2] = 0;
+
+ in = jas_stream_fopen(file.c_str(), "rb");
+
+ if(!in)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ gs.image = jas_image_decode(in, -1, 0);
+
+ jas_stream_close(in);
+
+ if(!gs.image)
+ return SQE_R_NOMEMORY;
+
+ s32 family = jas_clrspc_fam(jas_image_clrspc(gs.image));
+
+ if(!convert_colorspace())
+ return SQE_R_BADFILE;
+
+ jas_image_destroy(gs.image);
+ gs.image = gs.altimage;
+ gs.altimage = 0;
+
+ image.w = jas_image_width(gs.image);
+ image.h = jas_image_height(gs.image);
+
+ switch(family)
+ {
+ case JAS_CLRSPC_FAM_RGB:
+ image.colorspace = "RGB";
+ image.bpp = 24;
+ break;
+
+ case JAS_CLRSPC_FAM_YCBCR:
+ image.colorspace = "YCbCr";
+ image.bpp = 24;
+ break;
+
+ case JAS_CLRSPC_FAM_GRAY:
+ image.colorspace = "Grayscale";
+ image.bpp = 8;
+ break;
+
+ case JAS_CLRSPC_FAM_LAB:
+ image.colorspace = "LAB";
+ image.bpp = 24;
+ break;
+
+ default:
+ image.colorspace = "Unknown";
+ image.bpp = 0;
+ }
+
+ image.compression = "JPEG2000";
+
+ if((gs.cmptlut[0] = jas_image_getcmptbytype(gs.image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
+ (gs.cmptlut[1] = jas_image_getcmptbytype(gs.image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 ||
+ (gs.cmptlut[2] = jas_image_getcmptbytype(gs.image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0)
+
+ return SQE_R_NOMEMORY;
+
+ const s32 *cmptlut = gs.cmptlut;
+
+ // check that all components have the same size.
+ const s32 width = jas_image_cmptwidth(gs.image, cmptlut[0]);
+ const s32 height = jas_image_cmptheight(gs.image, cmptlut[0]);
+
+ for(s32 i = 1; i < 3; ++i)
+ {
+ if(jas_image_cmptwidth(gs.image, cmptlut[i]) != width ||
+ jas_image_cmptheight(gs.image, cmptlut[i]) != height)
+
+ return SQE_R_BADFILE;
+ }
+
+ for(s32 i = 0;i < 3;i++)
+ {
+ if(!(gs.data[i] = jas_matrix_create(1, image.w)))
+ return SQE_R_BADFILE;
+ }
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ jas_seqent_t v;
+
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ u8 *data = (u8 *)scan;
+
+ for(s32 cmptno = 0; cmptno < 3; ++cmptno)
+ {
+ if(jas_image_readcmpt(gs.image, gs.cmptlut[cmptno], 0, line, im->w, 1, gs.data[cmptno]))
+ return SQE_R_BADFILE;
+
+ gs.d[cmptno] = jas_matrix_getref(gs.data[cmptno], 0, 0);
+ }
+
+ for(s32 x = 0; x < im->w;++x)
+ {
+ for(int k = 0; k < 3; ++k)
+ {
+ v = *gs.d[k];
+
+ if(v < 0)
+ v = 0;
+ else if(v > 255)
+ v = 255;
+
+ *data = v;
+ data++;
+
+ ++gs.d[k];
+ }
+
+ data++;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ for(s32 cmptno = 0; cmptno < 3; ++cmptno)
+ {
+ if (gs.data[cmptno])
+ jas_matrix_destroy(gs.data[cmptno]);
+ }
+
+ if(gs.image) jas_image_destroy(gs.image);
+ if(gs.altimage) jas_image_destroy(gs.altimage);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+// helper method
+bool fmt_codec::convert_colorspace()
+{
+ jas_cmprof_t *outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB);
+
+ if(!outprof)
+ return false;
+
+ gs.altimage = jas_image_chclrspc(gs.image, outprof, JAS_CMXFORM_INTENT_PER);
+
+ if(!gs.altimage)
+ return false;
+
+ jas_cmprof_destroy(outprof);
+
+ return true;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_jpeg2000/fmt_codec_jpeg2000_defs.h b/kernel/kls_jpeg2000/fmt_codec_jpeg2000_defs.h
new file mode 100644
index 0000000..0fb6150
--- /dev/null
+++ b/kernel/kls_jpeg2000/fmt_codec_jpeg2000_defs.h
@@ -0,0 +1,28 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_jpeg2000
+#define KSQUIRREL_CODEC_DEFS_jpeg2000
+
+const float DEFAULT_RATE = 0.10;
+const unsigned MAXCMPTS = 256;
+
+#endif
diff --git a/kernel/kls_koala/Makefile.am b/kernel/kls_koala/Makefile.am
new file mode 100644
index 0000000..468bb0a
--- /dev/null
+++ b/kernel/kls_koala/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_koala.la
+
+libkls_koala_la_SOURCES = fmt_codec_koala.cpp fmt_codec_koala_defs.h
+
+libkls_koala_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_koala_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_koala/fmt_codec_koala.cpp b/kernel/kls_koala/fmt_codec_koala.cpp
new file mode 100644
index 0000000..2c91e48
--- /dev/null
+++ b/kernel/kls_koala/fmt_codec_koala.cpp
@@ -0,0 +1,207 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_koala_defs.h"
+#include "fmt_codec_koala.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_koala.xpm"
+
+// Code partially taken from FreeImage3
+
+/*
+ *
+ * Commodore 64 Koala
+ *
+ */
+
+const RGB c64pal[16] =
+{
+ RGB( 0, 0, 0 ), // Black
+ RGB( 255, 255, 255 ), // White
+ RGB( 170, 17, 17 ), // Red
+ RGB( 12, 204, 204 ), // Cyan
+ RGB( 221, 51, 221 ), // Purple
+ RGB( 0, 187, 0 ), // Green
+ RGB( 0, 0, 204 ), // Blue
+ RGB( 255, 255, 140 ), // Yellow
+ RGB( 204, 119, 34 ), // Orange
+ RGB( 136, 68, 0 ), // Brown
+ RGB( 255, 153, 136 ), // Light red
+ RGB( 92, 92, 92 ), // Gray 1
+ RGB( 170, 170, 170 ), // Gray 2
+ RGB( 140, 255, 178 ), // Light green
+ RGB( 39, 148, 255 ), // Light blue
+ RGB( 196, 196, 196 ) // Gray 3
+};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.2.2";
+ o->name = "Commodore 64 Koala";
+ o->filter = "*.koa *.kla ";
+ o->config = "";
+ o->mime = "\x0000\x0060";
+ o->mimetype = "image/x-koala";
+ o->pixmap = codec_koala;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ pixel_mask[0] = 0xc0;
+ pixel_mask[1] = 0x30;
+ pixel_mask[2] = 0x0c;
+ pixel_mask[3] = 0x03;
+
+ pixel_displ[0] = 6;
+ pixel_displ[1] = 4;
+ pixel_displ[2] = 2;
+ pixel_displ[3] = 0;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ u8 load[2];
+
+ if(!frs.readK(load, sizeof(load)))
+ return SQE_R_BADFILE;
+
+ if(load[0] != 0x00 || load[1] != 0x60)
+ {
+ ((u8 *)&koala)[0] = load[0];
+ ((u8 *)&koala)[1] = load[1];
+
+ if(!frs.readK((u8 *)&koala + 2, 10001 - 2))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ if(!frs.readK((u8 *)&koala, 10001))
+ return SQE_R_BADFILE;
+ }
+
+ foundcolor = 0;
+
+ image.w = KOALA_WIDTH;
+ image.h = KOALA_HEIGHT;
+ image.bpp = 8;
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(8);
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 x = 0;x < KOALA_WIDTH / 2;x++)
+ {
+ index = (x / 4) * 8 + (line % 8) + (line / 8) * KOALA_WIDTH;
+ colorindex = (x / 4) + (line / 8) * 40;
+ pixel = (koala.image[index] & pixel_mask[x % 4]) >> pixel_displ[x % 4];
+
+ // Retrieve RGB values
+ switch(pixel)
+ {
+ case 0: // Background
+ foundcolor = koala.background;
+ break;
+
+ case 1: // Color 1
+ foundcolor = koala.color1[colorindex] >> 4;
+ break;
+
+ case 2: // Color 2
+ foundcolor = koala.color1[colorindex] & 0xf;
+ break;
+
+ case 3: // Color 3
+ foundcolor = koala.color2[colorindex] & 0xf;
+ break;
+ }
+
+ memcpy(scan+x*2, c64pal+foundcolor, sizeof(RGB));
+ memcpy(scan+x*2+1, c64pal+foundcolor, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_koala/fmt_codec_koala_defs.h b/kernel/kls_koala/fmt_codec_koala_defs.h
new file mode 100644
index 0000000..c655f29
--- /dev/null
+++ b/kernel/kls_koala/fmt_codec_koala_defs.h
@@ -0,0 +1,39 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_koala
+#define KSQUIRREL_CODEC_DEFS_koala
+
+// Koala has constant width and height (like FLIC)
+
+#define KOALA_WIDTH 320
+#define KOALA_HEIGHT 200
+
+typedef struct
+{
+ u8 image[8000]; // pixmap image
+ u8 color1[1000]; // first colormap (color 1 and 2)
+ u8 color2[1000]; // second colormap (color 3)
+ u8 background; // background color
+
+} koala_t;
+
+#endif
diff --git a/kernel/kls_leaf/Makefile.am b/kernel/kls_leaf/Makefile.am
new file mode 100644
index 0000000..f71925f
--- /dev/null
+++ b/kernel/kls_leaf/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-leaf2ppm
+
+pkglib_LTLIBRARIES = libkls_leaf.la
+
+libkls_leaf_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_leaf_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_leaf_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_LEAF -DNETPBM_S=\"${bindir}/ksquirrel-libs-leaf2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-leaf2ppm.in \ No newline at end of file
diff --git a/kernel/kls_leaf/fmt_codec_pnm.cpp b/kernel/kls_leaf/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_leaf/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_leaf/fmt_codec_pnm_defs.h b/kernel/kls_leaf/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_leaf/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_leaf/ksquirrel-libs-leaf2ppm.in b/kernel/kls_leaf/ksquirrel-libs-leaf2ppm.in
new file mode 100644
index 0000000..3c77877
--- /dev/null
+++ b/kernel/kls_leaf/ksquirrel-libs-leaf2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@LEAFTOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_lif/Makefile.am b/kernel/kls_lif/Makefile.am
new file mode 100644
index 0000000..8375d24
--- /dev/null
+++ b/kernel/kls_lif/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_lif.la
+
+libkls_lif_la_SOURCES = fmt_codec_lif.cpp fmt_codec_lif_defs.h
+
+libkls_lif_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_lif_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_lif/fmt_codec_lif.cpp b/kernel/kls_lif/fmt_codec_lif.cpp
new file mode 100644
index 0000000..edc87b8
--- /dev/null
+++ b/kernel/kls_lif/fmt_codec_lif.cpp
@@ -0,0 +1,155 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_lif_defs.h"
+#include "fmt_codec_lif.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_lif.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.2";
+ o->name = "Homeworld LIF";
+ o->filter = "*.lif ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-lif";
+ o->pixmap = codec_lif;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.readK(&lif, sizeof(lif_header))) return SQE_R_BADFILE;
+/*
+ lif.version = fmt_utils::konvertLong(lif.version);
+ lif.flags = fmt_utils::konvertLong(lif.flags);
+ lif.width = fmt_utils::konvertLong(lif.width);
+ lif.height = fmt_utils::konvertLong(lif.height);
+ lif.palOffset = fmt_utils::konvertLong(lif.palOffset);
+
+
+ if(lif.version != LIF_VERSION || lif.flags != LIF_FLAGS)
+ return SQE_R_BADFILE;
+*/
+
+ if(strcmp(lif.id, LIF_ID))
+ return SQE_R_BADFILE;
+
+ image.w = lif.width;
+ image.h = lif.height;
+
+ fstream::pos_type pos = frs.tellg();
+
+ frs.seekg(lif.width * lif.height, ios::beg);
+
+ if(!frs.readK(pal, sizeof(pal)))
+ return SQE_R_BADFILE;
+
+ frs.seekg(pos);
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(8);
+ image.bpp = 8;
+ image.hasalpha = (bool)(lif.flags & 0x08);
+
+ bytes = image.hasalpha ? sizeof(RGBA) : sizeof(RGB);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u8 c;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return SQE_R_BADFILE;
+
+ c++;
+
+ memcpy(scan+i, pal+c, bytes);
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_lif/fmt_codec_lif_defs.h b/kernel/kls_lif/fmt_codec_lif_defs.h
new file mode 100644
index 0000000..cb0fd1c
--- /dev/null
+++ b/kernel/kls_lif/fmt_codec_lif_defs.h
@@ -0,0 +1,41 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_lif
+#define KSQUIRREL_CODEC_DEFS_lif
+
+#define LIF_VERSION 260
+#define LIF_FLAGS 50
+#define LIF_ID "Willy 7"
+
+struct lif_header
+{
+ s8 id[8]; // "Willy 7"
+ s32 version; // Version Number (260)
+ s32 flags; // Usually 50
+ s32 width;
+ s32 height;
+ u32 paletteCRC; // CRC of palettes for fast comparison.
+ u32 imageCRC; // CRC of the image.
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_ljpeg/Makefile.am b/kernel/kls_ljpeg/Makefile.am
new file mode 100644
index 0000000..e2f720d
--- /dev/null
+++ b/kernel/kls_ljpeg/Makefile.am
@@ -0,0 +1,17 @@
+SUBDIRS = ljpeg2ppm
+
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-ljpeg2ppm-s
+
+pkglib_LTLIBRARIES = libkls_ljpeg.la
+
+libkls_ljpeg_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_ljpeg_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_ljpeg_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_LJPEG -DLJPEG2PPM_S=\"${bindir}/ksquirrel-libs-ljpeg2ppm-s\" -DLJPEG2PPM=\"${bindir}/ksquirrel-libs-ljpeg2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-ljpeg2ppm-s.in
diff --git a/kernel/kls_ljpeg/fmt_codec_pnm.cpp b/kernel/kls_ljpeg/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_ljpeg/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_ljpeg/fmt_codec_pnm_defs.h b/kernel/kls_ljpeg/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_ljpeg/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in b/kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in
new file mode 100644
index 0000000..74c3038
--- /dev/null
+++ b/kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+kls_ljpeg_i=""
+kls_ljpeg_o=""
+kls_ljpeg_bin=""
+
+while [ "$1" ] ; do
+
+ case "$1" in
+ "--input") kls_ljpeg_i="$2" shift ;;
+ "--output") kls_ljpeg_o="$2" shift ;;
+ "--binary") kls_ljpeg_bin="$2" shift ;;
+ esac
+
+shift
+done
+
+$kls_ljpeg_bin "$kls_ljpeg_i" > "$kls_ljpeg_o" \ No newline at end of file
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/Copyright b/kernel/kls_ljpeg/ljpeg2ppm/Copyright
new file mode 100644
index 0000000..5fae625
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/Copyright
@@ -0,0 +1,79 @@
+Copyright (c) 1993 Cornell University, Kongji Huang
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for research purposes, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+
+Copyright (c) 1993 The Regents of the University of California, Brian
+C. Smith All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+IJG Copyright
+
+The authors make NO WARRANTY or representation, either express or
+implied, with respect to this software, its quality, accuracy,
+merchantability, or fitness for a particular purpose. This software is
+provided "AS IS", and you, its user, assume the entire risk as to its
+quality and accuracy.
+
+This software is copyright (C) 1991, 1992, Thomas G. Lane. All Rights
+Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to
+these conditions: (1) If any part of the source code for this software
+is distributed, then this README file must be included, with this
+copyright and no-warranty notice unaltered; and any additions,
+deletions, or changes to the original files must be clearly indicated
+in accompanying documentation. (2) If only executable code is
+distributed, then the accompanying documentation must state that "this
+software is based in part on the work of the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user
+accepts full responsibility for any undesirable consequences; the
+authors accept NO LIABILITY for damages of any kind.
+
+Permission is NOT granted for the use of any IJG author's name or
+company name in advertising or publicity relating to this software or
+products derived from it. This software may be referred to only as
+"the Independent JPEG Group's software".
+
+We specifically permit and encourage the use of this software as the
+basis of commercial products, provided that all warranty or liability
+claims are assumed by the product vendor.
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am b/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am
new file mode 100644
index 0000000..8d9632e
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am
@@ -0,0 +1,5 @@
+#INCLUDES = -I../include
+
+bin_PROGRAMS = ksquirrel-libs-ljpeg2ppm
+
+ksquirrel_libs_ljpeg2ppm_SOURCES = huffd.c io.h jpeg.h ljpgtopnm.c mcu.c mcu.h predictor.c predictor.h proto.h read.c util.c
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/huffd.c b/kernel/kls_ljpeg/ljpeg2ppm/huffd.c
new file mode 100644
index 0000000..da5d2e9
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/huffd.c
@@ -0,0 +1,665 @@
+/*
+ * huffd.c --
+ *
+ * Code for JPEG lossless decoding. Large parts are grabbed from the IJG
+ * software, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "io.h"
+#include "proto.h"
+#include "predictor.h"
+
+#define RST0 0xD0 /* RST0 marker code */
+
+static long getBuffer; /* current bit-extraction buffer */
+static int bitsLeft; /* # of unused bits in it */
+
+/*
+ * The following variables keep track of the input buffer
+ * for the JPEG data, which is read by ReadJpegData.
+ */
+Uchar inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
+int numInputBytes; /* The total number of bytes in inputBuffer */
+int maxInputBytes; /* Size of inputBuffer */
+int inputBufferOffset; /* Offset of current byte */
+
+/*
+ * Code for extracting the next N bits from the input stream.
+ * (N never exceeds 15 for JPEG data.)
+ * This needs to go as fast as possible!
+ *
+ * We read source bytes into getBuffer and dole out bits as needed.
+ * If getBuffer already contains enough bits, they are fetched in-line
+ * by the macros get_bits() and get_bit(). When there aren't enough bits,
+ * FillBitBuffer is called; it will attempt to fill getBuffer to the
+ * "high water mark", then extract the desired number of bits. The idea,
+ * of course, is to minimize the function-call overhead cost of entering
+ * FillBitBuffer.
+ * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
+ * of getBuffer to be used. (On machines with wider words, an even larger
+ * buffer could be used.)
+ */
+
+#define BITS_PER_LONG (8*sizeof(long))
+#define MIN_GET_BITS (BITS_PER_LONG-7) /* max value for long getBuffer */
+
+/*
+ * bmask[n] is mask for n rightmost bits
+ */
+static int bmask[] = {0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000F,
+ 0x001F, 0x003F, 0x007F, 0x00FF,
+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
+ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FillBitBuffer --
+ *
+ * Load up the bit buffer with at least nbits
+ * Process any stuffed bytes at this time.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The bitwise global variables are updated.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+FillBitBuffer (nbits)
+ int nbits;
+{
+ int c, c2;
+
+ while (bitsLeft < MIN_GET_BITS) {
+ c = GetJpegChar ();
+
+ /*
+ * If it's 0xFF, check and discard stuffed zero byte
+ */
+ if (c == 0xFF) {
+ c2 = GetJpegChar ();
+
+ if (c2 != 0) {
+
+ /*
+ * Oops, it's actually a marker indicating end of
+ * compressed data. Better put it back for use later.
+ */
+ UnGetJpegChar (c2);
+ UnGetJpegChar (c);
+
+ /*
+ * There should be enough bits still left in the data
+ * segment; if so, just break out of the while loop.
+ */
+ if (bitsLeft >= nbits)
+ break;
+
+ /*
+ * Uh-oh. Corrupted data: stuff zeroes into the data
+ * stream, since this sometimes occurs when we are on the
+ * last show_bits(8) during decoding of the Huffman
+ * segment.
+ */
+ c = 0;
+ }
+ }
+ /*
+ * OK, load c into getBuffer
+ */
+ getBuffer = (getBuffer << 8) | c;
+ bitsLeft += 8;
+ }
+}
+
+/* Macros to make things go at some speed! */
+/* NB: parameter to get_bits should be simple variable, not expression */
+
+#define show_bits(nbits,rv) { \
+ if (bitsLeft < nbits) FillBitBuffer(nbits); \
+ rv = (getBuffer >> (bitsLeft-(nbits))) & bmask[nbits]; \
+}
+
+#define show_bits8(rv) { \
+ if (bitsLeft < 8) FillBitBuffer(8); \
+ rv = (getBuffer >> (bitsLeft-8)) & 0xff; \
+}
+
+#define flush_bits(nbits) { \
+ bitsLeft -= (nbits); \
+}
+
+#define get_bits(nbits,rv) { \
+ if (bitsLeft < nbits) FillBitBuffer(nbits); \
+ rv = ((getBuffer >> (bitsLeft -= (nbits)))) & bmask[nbits]; \
+}
+
+#define get_bit(rv) { \
+ if (!bitsLeft) FillBitBuffer(1); \
+ rv = (getBuffer >> (--bitsLeft)) & 1; \
+}
+
+#ifdef DEBUG
+/*
+ *--------------------------------------------------------------
+ *
+ * PmPutRow --
+ *
+ * Output one row of pixels stored in RowBuf.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * One row of pixels are write to file pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+PmPutRow(RowBuf,numComp,numCol,Pt)
+ MCU *RowBuf;
+ int numCol,Pt;
+{
+ register int col,v;
+
+ /*
+ * Mulitply 2^Pt before output. Pt is the point
+ * transform parameter.
+ */
+ if (numComp==1) { /*pgm*/
+ for (col = 0; col < numCol; col++) {
+ v=RowBuf[col][0]<<Pt;
+ (void)putc(v,outFile);
+ }
+ } else { /*ppm*/
+ for (col = 0; col < numCol; col++) {
+ v=RowBuf[col][0]<<Pt;
+ (void)putc(v,outFile);
+ v=RowBuf[col][1]<<Pt;
+ (void)putc(v,outFile);
+ v=RowBuf[col][2]<<Pt;
+ (void)putc(v,outFile);
+ }
+ }
+}
+#else
+/*
+ *--------------------------------------------------------------
+ *
+ * PmPutRow --
+ *
+ * Output one row of pixels stored in RowBuf.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * One row of pixels are write to file pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+#define PmPutRow(RowBuf,numComp,numCol,Pt) \
+{ register int col,v; \
+ if (numComp==1) { /*pgm*/ \
+ for (col = 0; col < numCol; col++) { \
+ v=RowBuf[col][0]<<Pt; \
+ (void)putc(v,outFile); \
+ } \
+ } else { /*ppm*/ \
+ for (col = 0; col < numCol; col++) { \
+ v=RowBuf[col][0]<<Pt; \
+ (void)putc(v,outFile); \
+ v=RowBuf[col][1]<<Pt; \
+ (void)putc(v,outFile); \
+ v=RowBuf[col][2]<<Pt; \
+ (void)putc(v,outFile); \
+ } \
+ } \
+}
+#endif
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffDecode --
+ *
+ * Taken from Figure F.16: extract next coded symbol from
+ * input stream. This should becode a macro.
+ *
+ * Results:
+ * Next coded symbol
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+#define HuffDecode(htbl,rv) \
+{ \
+ int l, code, temp; \
+ \
+ /* \
+ * If the huffman code is less than 8 bits, we can use the fast \
+ * table lookup to get its value. It's more than 8 bits about \
+ * 3-4% of the time. \
+ */ \
+ show_bits8(code); \
+ if (htbl->numbits[code]) { \
+ flush_bits(htbl->numbits[code]); \
+ rv=htbl->value[code]; \
+ } else { \
+ flush_bits(8); \
+ l = 8; \
+ while (code > htbl->maxcode[l]) { \
+ get_bit(temp); \
+ code = (code << 1) | temp; \
+ l++; \
+ } \
+ \
+ /* \
+ * With garbage input we may reach the sentinel value l = 17. \
+ */ \
+ \
+ if (l > 16) { \
+ fprintf (stderr, "Corrupt JPEG data: bad Huffman code"); \
+ rv = 0; /* fake a zero as the safest result */ \
+ } else { \
+ rv = htbl->huffval[htbl->valptr[l] + \
+ ((int)(code - htbl->mincode[l]))]; \
+ } \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffExtend --
+ *
+ * Code and table for Figure F.12: extend sign bit
+ *
+ * Results:
+ * The extended value.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+static int extendTest[16] = /* entry n is 2**(n-1) */
+{0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
+
+static int extendOffset[16] = /* entry n is (-1 << n) + 1 */
+{0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
+ ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
+ ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
+ ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
+
+#define HuffExtend(x,s) { \
+ if ((x) < extendTest[s]) { \
+ (x) += extendOffset[s]; \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffDecoderInit --
+ *
+ * Initialize for a Huffman-compressed scan.
+ * This is invoked after reading the SOS marker.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+HuffDecoderInit (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ short ci;
+ JpegComponentInfo *compptr;
+
+ /*
+ * Initialize static variables
+ */
+ bitsLeft = 0;
+
+ for (ci = 0; ci < dcPtr->compsInScan; ci++) {
+ compptr = dcPtr->curCompInfo[ci];
+ /*
+ * Make sure requested tables are present
+ */
+ if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
+ fprintf (stderr, "Error: Use of undefined Huffman table\n");
+ exit (1);
+ }
+
+ /*
+ * Compute derived values for Huffman tables.
+ * We may do this more than once for same table, but it's not a
+ * big deal
+ */
+ FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
+ }
+
+ /*
+ * Initialize restart stuff
+ */
+ dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
+ dcPtr->restartRowsToGo = dcPtr->restartInRows;
+ dcPtr->nextRestartNum = 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ProcessRestart --
+ *
+ * Check for a restart marker & resynchronize decoder.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * BitStream is parsed, bit buffer is reset, etc.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+ProcessRestart (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, nbytes;
+ short ci;
+
+ /*
+ * Throw away any unused bits remaining in bit buffer
+ */
+ nbytes = bitsLeft / 8;
+ bitsLeft = 0;
+
+ /*
+ * Scan for next JPEG marker
+ */
+ do {
+ do { /* skip any non-FF bytes */
+ nbytes++;
+ c = GetJpegChar ();
+ } while (c != 0xFF);
+ do { /* skip any duplicate FFs */
+ /*
+ * we don't increment nbytes here since extra FFs are legal
+ */
+ c = GetJpegChar ();
+ } while (c == 0xFF);
+ } while (c == 0); /* repeat if it was a stuffed FF/00 */
+
+ if (c != (RST0 + dcPtr->nextRestartNum)) {
+
+ /*
+ * Uh-oh, the restart markers have been messed up too.
+ * Just bail out.
+ */
+ fprintf (stderr, "Error: Corrupt JPEG data. Exiting...\n");
+ exit(-1);
+ }
+
+ /*
+ * Update restart state
+ */
+ dcPtr->restartRowsToGo = dcPtr->restartInRows;
+ dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeFirstRow --
+ *
+ * Decode the first raster line of samples at the start of
+ * the scan and at the beginning of each restart interval.
+ * This includes modifying the component value so the real
+ * value, not the difference is returned.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void DecodeFirstRow(dcPtr,curRowBuf)
+ DecompressInfo *dcPtr;
+ MCU *curRowBuf;
+{
+ register short curComp,ci;
+ register int s,col,compsInScan,numCOL;
+ register JpegComponentInfo *compptr;
+ int Pr,Pt,d;
+ HuffmanTable *dctbl;
+
+ Pr=dcPtr->dataPrecision;
+ Pt=dcPtr->Pt;
+ compsInScan=dcPtr->compsInScan;
+ numCOL=dcPtr->imageWidth;
+
+ /*
+ * the start of the scan or at the beginning of restart interval.
+ */
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ /*
+ * Add the predictor to the difference.
+ */
+ curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
+ }
+
+ /*
+ * the rest of the first row
+ */
+ for (col=1; col<numCOL; col++) {
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ /*
+ * Add the predictor to the difference.
+ */
+ curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
+ }
+ }
+
+ if (dcPtr->restartInRows) {
+ (dcPtr->restartRowsToGo)--;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeImage --
+ *
+ * Decode the input stream. This includes modifying
+ * the component value so the real value, not the
+ * difference is returned.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void
+DecodeImage(dcPtr)
+ DecompressInfo *dcPtr;
+{
+ register int s,d,col,row;
+ register short curComp, ci;
+ HuffmanTable *dctbl;
+ JpegComponentInfo *compptr;
+ int predictor;
+ int numCOL,numROW,compsInScan;
+ MCU *prevRowBuf,*curRowBuf;
+ int imagewidth,Pt,psv;
+
+ numCOL=imagewidth=dcPtr->imageWidth;
+ numROW=dcPtr->imageHeight;
+ compsInScan=dcPtr->compsInScan;
+ Pt=dcPtr->Pt;
+ psv=dcPtr->Ss;
+ prevRowBuf=mcuROW2;
+ curRowBuf=mcuROW1;
+
+ /*
+ * Decode the first row of image. Output the row and
+ * turn this row into a previous row for later predictor
+ * calculation.
+ */
+ DecodeFirstRow(dcPtr,curRowBuf);
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+
+ for (row=1; row<numROW; row++) {
+
+ /*
+ * Account for restart interval, process restart marker if needed.
+ */
+ if (dcPtr->restartInRows) {
+ if (dcPtr->restartRowsToGo == 0) {
+ ProcessRestart (dcPtr);
+
+ /*
+ * Reset predictors at restart.
+ */
+ DecodeFirstRow(dcPtr,curRowBuf);
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+ continue;
+ }
+ dcPtr->restartRowsToGo--;
+ }
+
+ /*
+ * The upper neighbors are predictors for the first column.
+ */
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
+ }
+
+ /*
+ * For the rest of the column on this row, predictor
+ * calculations are base on PSV.
+ */
+ for (col=1; col<numCOL; col++) {
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+ QuickPredict(col,curComp,curRowBuf,prevRowBuf,
+ psv,&predictor);
+
+ curRowBuf[col][curComp]=d+predictor;
+ }
+ }
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+ }
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/io.h b/kernel/kls_ljpeg/ljpeg2ppm/io.h
new file mode 100644
index 0000000..65d9636
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/io.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _IO
+#define _IO
+
+/*
+ * Size of the input and output buffer
+ */
+#define JPEG_BUF_SIZE 4096
+
+/*
+ * The following variables keep track of the input and output
+ * buffer for the JPEG data.
+ */
+extern char outputBuffer[JPEG_BUF_SIZE]; /* output buffer */
+extern int numOutputBytes; /* bytes in the output buffer */
+extern Uchar inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
+extern int numInputBytes; /* bytes in inputBuffer */
+extern int maxInputBytes; /* Size of inputBuffer */
+extern int inputBufferOffset; /* Offset of current byte */
+
+/*
+ * the output file pointer.
+ */
+extern FILE *outFile;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * EmitByte --
+ *
+ * Write a single byte out to the output buffer, and
+ * flush if it's full.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The outp[ut buffer may get flushed.
+ *
+ *--------------------------------------------------------------
+ */
+#define EmitByte(val) { \
+ if (numOutputBytes >= JPEG_BUF_SIZE) { \
+ FlushBytes(); \
+ } \
+ outputBuffer[numOutputBytes++] = (char)(val); \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetJpegChar, UnGetJpegChar --
+ *
+ * Macros to get the next character from the input stream.
+ *
+ * Results:
+ * GetJpegChar returns the next character in the stream, or EOF
+ * UnGetJpegChar returns nothing.
+ *
+ * Side effects:
+ * A byte is consumed or put back into the inputBuffer.
+ *
+ *--------------------------------------------------------------
+ */
+#define GetJpegChar() \
+ ((inputBufferOffset < numInputBytes)? \
+ inputBuffer[inputBufferOffset++]: \
+ (numInputBytes = 2+ReadJpegData(inputBuffer+2,JPEG_BUF_SIZE-2), \
+ inputBufferOffset = 2, \
+ ((inputBufferOffset < numInputBytes)? \
+ inputBuffer[inputBufferOffset++]: \
+ EOF)))
+
+#define UnGetJpegChar(ch) (inputBuffer[--inputBufferOffset]=(ch))
+
+#endif /* _IO */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h b/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h
new file mode 100644
index 0000000..44a41cb
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h
@@ -0,0 +1,249 @@
+/*
+ * jpeg.h --
+ *
+ * Basic jpeg data structure definitions.
+ *
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _JPEG
+#define _JPEG
+
+typedef unsigned char Uchar;
+typedef unsigned short Ushort;
+typedef unsigned int Uint;
+
+/*
+ * The following structure stores basic information about one component.
+ */
+typedef struct JpegComponentInfo {
+ /*
+ * These values are fixed over the whole image.
+ * They are read from the SOF marker.
+ */
+ short componentId; /* identifier for this component (0..255) */
+ short componentIndex; /* its index in SOF or cPtr->compInfo[] */
+
+ /*
+ * Downsampling is not normally used in lossless JPEG, although
+ * it is permitted by the JPEG standard (DIS). We set all sampling
+ * factors to 1 in this program.
+ */
+ short hSampFactor; /* horizontal sampling factor */
+ short vSampFactor; /* vertical sampling factor */
+
+ /*
+ * Huffman table selector (0..3). The value may vary
+ * between scans. It is read from the SOS marker.
+ */
+ short dcTblNo;
+} JpegComponentInfo;
+
+
+/*
+ * One of the following structures is created for each huffman coding
+ * table. We use the same structure for encoding and decoding, so there
+ * may be some extra fields for encoding that aren't used in the decoding
+ * and vice-versa.
+ */
+typedef struct HuffmanTable {
+ /*
+ * These two fields directly represent the contents of a JPEG DHT
+ * marker
+ */
+ Uchar bits[17];
+ Uchar huffval[256];
+
+ /*
+ * This field is used only during compression. It's initialized
+ * FALSE when the table is created, and set TRUE when it's been
+ * output to the file.
+ */
+ int sentTable;
+
+ /*
+ * The remaining fields are computed from the above to allow more
+ * efficient coding and decoding. These fields should be considered
+ * private to the Huffman compression & decompression modules.
+ */
+ Ushort ehufco[256];
+ char ehufsi[256];
+
+ Ushort mincode[17];
+ int maxcode[18];
+ short valptr[17];
+ int numbits[256];
+ int value[256];
+} HuffmanTable;
+
+/*
+ * One of the following structures is used to pass around the
+ * compression information.
+ */
+typedef struct CompressInfo {
+ /*
+ * Image width, height, and image data precision (bits/sample)
+ */
+ int imageWidth;
+ int imageHeight;
+ int dataPrecision;
+
+ /*
+ * compInfo[i] describes component that appears i'th in SOF
+ * numComponents is the # of color components in JPEG image.
+ */
+ JpegComponentInfo *compInfo;
+ short numComponents;
+
+ /*
+ * *curCompInfo[i] describes component that appears i'th in SOS.
+ * compsInScan is the # of color components in current scan.
+ */
+ JpegComponentInfo *curCompInfo[4];
+ short compsInScan;
+
+ /*
+ * MCUmembership[i] indexes the i'th component of MCU into the
+ * curCompInfo array.
+ */
+ short MCUmembership[10];
+
+ /*
+ * Pointers to Huffman coding tables, or NULL if not defined.
+ */
+ HuffmanTable *dcHuffTblPtrs[4];
+
+ /*
+ * prediction seletion value (PSV) and point transform parameter (Pt)
+ */
+ int Ss;
+ int Pt;
+
+ /*
+ * In lossless JPEG, restart interval shall be an integer
+ * multiple of the number of MCU in a MCU row.
+ */
+ int restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
+
+ /*
+ * These fields are private data for the entropy encoder
+ */
+ int restartRowsToGo; /* MCUs rows left in this restart interval */
+ short nextRestartNum; /* # of next RSTn marker (0..7) */
+} CompressInfo;
+
+/*
+ * One of the following structures is used to pass around the
+ * decompression information.
+ */
+typedef struct DecompressInfo {
+ /*
+ * Image width, height, and image data precision (bits/sample)
+ * These fields are set by ReadFileHeader or ReadScanHeader
+ */
+ int imageWidth;
+ int imageHeight;
+ int dataPrecision;
+
+ /*
+ * compInfo[i] describes component that appears i'th in SOF
+ * numComponents is the # of color components in JPEG image.
+ */
+ JpegComponentInfo *compInfo;
+ short numComponents;
+
+ /*
+ * *curCompInfo[i] describes component that appears i'th in SOS.
+ * compsInScan is the # of color components in current scan.
+ */
+ JpegComponentInfo *curCompInfo[4];
+ short compsInScan;
+
+ /*
+ * MCUmembership[i] indexes the i'th component of MCU into the
+ * curCompInfo array.
+ */
+ short MCUmembership[10];
+
+ /*
+ * ptrs to Huffman coding tables, or NULL if not defined
+ */
+ HuffmanTable *dcHuffTblPtrs[4];
+
+ /*
+ * prediction seletion value (PSV) and point transform parameter (Pt)
+ */
+ int Ss;
+ int Pt;
+
+ /*
+ * In lossless JPEG, restart interval shall be an integer
+ * multiple of the number of MCU in a MCU row.
+ */
+ int restartInterval;/* MCUs per restart interval, 0 = no restart */
+ int restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
+
+ /*
+ * these fields are private data for the entropy decoder
+ */
+ int restartRowsToGo; /* MCUs rows left in this restart interval */
+ short nextRestartNum; /* # of next RSTn marker (0..7) */
+} DecompressInfo;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * swap --
+ *
+ * Swap the contents stored in a and b.
+ * "type" is the variable type of a and b.
+ *
+ * Results:
+ * The values in a and b are swapped.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define swap(type,a,b) {type c; c=(a); (a)=(b); (b)=c;}
+
+#define MEMSET(s,c,n) memset((void *)(s),(int)(c),(int)(n))
+#define MEMCPY(s1,s2,n) memcpy((void *)(s1),(void *)(s2),(int)(n))
+
+/*
+ * Lossless JPEG specifies data precision to be from 2 to 16 bits/sample.
+ */
+#define MinPrecisionBits 2
+#define MaxPrecisionBits 16
+#define MinPrecisionValue 2
+#define MaxPrecisionValue 65535
+
+#endif /* _JPEG */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c b/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c
new file mode 100644
index 0000000..c975892
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c
@@ -0,0 +1,263 @@
+/*
+ * ljpgtopnm.c --
+ *
+ * This is the main routine for the lossless JPEG decoder. Large
+ * parts are stolen from the IJG code, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+/*
+ * input and output file pointers
+ */
+FILE *inFile, *outFile;
+void FreeArray2D(char **);
+
+void WritePmHeader(DecompressInfo dcInfo);
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadJpegData --
+ *
+ * This is an interface routine to the JPEG library. The
+ * JPEG library calls this routine to "get more data"
+ *
+ * Results:
+ * Number of bytes actually returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+int
+ReadJpegData (buffer, numBytes)
+ char *buffer; /* Place to put new data */
+ int numBytes; /* Number of bytes to put */
+{
+ return fread(buffer, 1, numBytes, inFile);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * WritePmHeader --
+ *
+ * Output Portable Pixmap (PPM) or Portable
+ * Graymap (PGM) image header.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The PPM or PGM header is written to file
+ * pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+void
+WritePmHeader(dcInfo)
+DecompressInfo dcInfo;
+{
+ switch(dcInfo.numComponents) {
+ case 1: /* pgm */
+ if (dcInfo.dataPrecision==8) {
+ fprintf(outFile,"P5\n%d %d\n255\n",
+ dcInfo.imageWidth,dcInfo.imageHeight);
+ } else {
+ fprintf(outFile,"P5\n%d %d\n%d\n",
+ dcInfo.imageWidth,dcInfo.imageHeight,
+ ((1<<dcInfo.dataPrecision)-1));
+ }
+ break;
+ case 3: /* ppm */
+ if (dcInfo.dataPrecision==8) {
+ fprintf(outFile,"P6\n%d %d\n255\n",
+ dcInfo.imageWidth,dcInfo.imageHeight);
+ } else {
+ fprintf(outFile,"P6\n%d %d\n%d\n",
+ dcInfo.imageWidth,dcInfo.imageHeight,
+ ((1<<dcInfo.dataPrecision)-1));
+ }
+ break;
+ default:
+ fprintf(stderr,"Error: Unsupported image format.\n");
+ exit(-1);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ArgParser --
+ *
+ * Command line parser.
+ *
+ * Results:
+ * Command line parameters and options are passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+ArgParser(argc,argv,verbose,linFile,loutFile)
+ int argc;
+ char **argv;
+ int *verbose;
+ FILE **linFile, **loutFile;
+{
+ int argn;
+ char *arg;
+ const char *usage="ppmtoljpeg [ -v -h ] [ inFile [outFile] ]";
+ int NumOfFile=0;
+
+ /*
+ * default values
+ */
+ *linFile=stdin;
+ *loutFile=stdout;
+ *verbose=0;
+
+ for (argn = 1; argn < argc; argn++) {
+ arg=argv[argn];
+ if (*arg != '-') { /* process a file name */
+ if (NumOfFile==0) {
+ if ((*linFile=fopen(arg,"r"))==NULL) {
+ fprintf(stderr,"Can't open %s\n",arg);
+ exit(-1);
+ }
+ }
+ if (NumOfFile==1) {
+ if ((*loutFile=fopen(arg,"w"))==NULL) {
+ fprintf(stderr,"Can't open %s\n",arg);
+ exit(-1);
+ }
+ }
+ if (NumOfFile>1) {
+ fprintf(stderr,"%s\n",usage);
+ exit(-1);
+ }
+ NumOfFile++;
+ }
+ else { /* precess a option */
+ arg++;
+ switch (*arg) {
+ case 'h':
+ /* help flag */
+ fprintf(stderr,"Decode a lossless JPEG image into ");
+ fprintf(stderr,"a PPM or PGM image.\n");
+ fprintf(stderr,"Usage:\n");
+ fprintf(stderr,"%s\n",usage);
+ fprintf(stderr,"Default input: stdin\n");
+ fprintf(stderr,"Default output: stdout\n");
+ fprintf(stderr,"-h help\n");
+ fprintf(stderr,"-v verbose\n");
+ exit(1);
+ break;
+ case 'v':
+ /* verbose flag */
+ *verbose=1;
+ break;
+ default:
+ fprintf(stderr,"%s\n",usage);
+ exit(-1);
+ }
+ }
+ }
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ DecompressInfo dcInfo;
+ int verbose;
+
+ /*
+ * Process command line parameters.
+ */
+ MEMSET(&dcInfo, 0, sizeof(dcInfo));
+ ArgParser(argc,argv,&verbose,&inFile,&outFile);
+
+ /*
+ * Read the JPEG File header, up to scan header, and initialize all
+ * the variables in the decompression information structure.
+ */
+ ReadFileHeader (&dcInfo);
+
+ /*
+ * Loop through each scan in image. ReadScanHeader returns
+ * 0 once it consumes and EOI marker.
+ */
+ if (!ReadScanHeader (&dcInfo)) {
+ fprintf (stderr, "Empty JPEG file\n");
+ exit (1);
+ }
+
+ /*
+ * Output image parameter if verbose flag is on.
+ */
+ if (verbose) {
+ fprintf(stderr,"sample precision=%d\n",dcInfo.dataPrecision);
+ fprintf(stderr,"image height=%d\n",dcInfo.imageHeight);
+ fprintf(stderr,"image width=%d\n",dcInfo.imageWidth);
+ fprintf(stderr,"component=%d\n",dcInfo.numComponents);
+ }
+
+ /*
+ * Write PPM or PGM image header. Decode the image bits
+ * stream. Clean up everything when finished decoding.
+ */
+ WritePmHeader(dcInfo);
+ DecoderStructInit(&dcInfo);
+ HuffDecoderInit(&dcInfo);
+ DecodeImage(&dcInfo);
+ FreeArray2D(mcuROW1);
+ FreeArray2D(mcuROW2);
+
+ if (ReadScanHeader (&dcInfo)) {
+ fprintf (stderr, "Warning: multiple scans detected in JPEG file\n");
+ fprintf (stderr, " not currently supported\n");
+ fprintf (stderr, " ignoring extra scans\n");
+ }
+
+ return 0;
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/mcu.c b/kernel/kls_ljpeg/ljpeg2ppm/mcu.c
new file mode 100644
index 0000000..bb1f0b3
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/mcu.c
@@ -0,0 +1,125 @@
+/*
+ * mcu.c --
+ *
+ * Support for MCU allocation, deallocation, and printing.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+MCU *mcuTable; /* the global mcu table that buffers the source image */
+MCU *mcuROW1, *mcuROW2; /* point to two rows of MCU in encoding & decoding */
+int numMCU; /* number of MCUs in mcuTable */
+/*
+ *--------------------------------------------------------------
+ *
+ * MakeMCU, InitMcuTable --
+ *
+ * InitMcuTable does a big malloc to get the amount of memory
+ * we'll need for storing MCU's, once we know the size of our
+ * input and output images.
+ * MakeMCU returns an MCU for input parsing.
+ *
+ * Results:
+ * A new MCU
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+InitMcuTable(lnumMCU,compsInScan)
+ int lnumMCU;
+ int compsInScan;
+{
+ int i, mcuSize;
+ char *buffer;
+
+ /*
+ * Compute size of on MCU (in bytes). Round up so it's on a
+ * boundary for any alignment. In this code, we assume this
+ * is a whole multiple of sizeof(double).
+ */
+ mcuSize = compsInScan * sizeof(ComponentType);
+ mcuSize = JroundUp(mcuSize,sizeof(double));
+
+ /*
+ * Allocate the MCU table, and a buffer which will contain all
+ * the data. Then carve up the buffer by hand. Note that
+ * mcuTable[0] points to the buffer, in case we want to free
+ * it up later.
+ */
+ mcuTable = (MCU *)malloc(lnumMCU * sizeof(MCU));
+ if (mcuTable==NULL)
+ fprintf(stderr,"Not enough memory for mcuTable\n");
+ buffer = (char *)malloc(lnumMCU * mcuSize);
+ if (buffer==NULL)
+ fprintf(stderr,"Not enough memory for buffer\n");
+ for (i=0; i<lnumMCU; i++) {
+ mcuTable[i] = (MCU)(buffer + i*mcuSize);
+ }
+}
+
+#define MakeMCU(dcPtr) (mcuTable[numMCU++])
+
+/*
+ *--------------------------------------------------------------
+ *
+ * PrintMCU --
+ *
+ * Send an MCU in quasi-readable form to stdout.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+PrintMCU (compsInScan, mcu)
+ int compsInScan;
+ MCU mcu;
+{
+ ComponentType r;
+ int b;
+ static int callCount;
+
+ for (b=0; b<compsInScan; b++) {
+ callCount++;
+ r = mcu[b];
+ printf ("%d: %d ", callCount, r);
+ printf ("\n");
+ }
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/mcu.h b/kernel/kls_ljpeg/ljpeg2ppm/mcu.h
new file mode 100644
index 0000000..bb894e6
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/mcu.h
@@ -0,0 +1,63 @@
+/*
+ * mcu.h --
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _MCU
+#define _MCU
+
+/*
+ * An MCU (minimum coding unit) is an array of samples.
+ */
+typedef short ComponentType; /* the type of image components */
+typedef ComponentType *MCU; /* MCU - array of samples */
+
+extern MCU *mcuTable; /* the global mcu table that buffers the source image */
+extern int numMCU; /* number of MCUs in mcuTable */
+extern MCU *mcuROW1,*mcuROW2; /* pt to two rows of MCU in encoding & decoding */
+
+/*
+ *--------------------------------------------------------------
+ *
+ * MakeMCU --
+ *
+ * MakeMCU returns an MCU for input parsing.
+ *
+ * Results:
+ * A new MCU
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define MakeMCU(dcPtr) (mcuTable[numMCU++])
+
+#endif /* _MCU */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/predictor.c b/kernel/kls_ljpeg/ljpeg2ppm/predictor.c
new file mode 100644
index 0000000..36dedfd
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/predictor.c
@@ -0,0 +1,189 @@
+/*
+ * predictor.c --
+ *
+ * Code for predictor calculation. Its macro version, predictor.h,
+ * is used in non-debugging compilation.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include "mcu.h"
+
+#ifdef DEBUG
+/*
+ *--------------------------------------------------------------
+ *
+ * Predict --
+ *
+ * Calculate the predictor for pixel[row][col][curComp],
+ * i.e. curRowBuf[col][curComp]. It handles the all special
+ * cases at image edges, such as first row and first column
+ * of a scan.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor)
+ int row,col; /* position of the pixel to be predicted */
+ int curComp; /* the pixel's component that is predicting */
+ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */
+ int Pr; /* data precision */
+ int Pt; /* point transformation */
+ int psv; /* predictor selection value */
+ int *predictor; /* preditor value (output) */
+{
+ register int left,upper,diag,leftcol;
+
+ leftcol=col-1;
+ if (row==0) {
+
+ /*
+ * The predictor of first pixel is (1<<(Pr-Pt-1), and the
+ * predictors for rest of first row are left neighbors.
+ */
+ if (col==0) {
+ *predictor = (1<<(Pr-Pt-1));
+ }
+ else {
+ *predictor = curRowBuf[leftcol][curComp];
+ }
+ }
+ else {
+
+ /*
+ * The predictors of first column are upper neighbors.
+ * All other preditors are calculated according to psv.
+ */
+ upper=prevRowBuf[col][curComp];
+ if (col==0)
+ *predictor = upper;
+ else {
+ left=curRowBuf[leftcol][curComp];
+ diag=prevRowBuf[leftcol][curComp];
+ switch (psv) {
+ case 0:
+ *predictor = 0;
+ break;
+ case 1:
+ *predictor = left;
+ break;
+ case 2:
+ *predictor = upper;
+ break;
+ case 3:
+ *predictor = diag;
+ break;
+ case 4:
+ *predictor = left+upper-diag;
+ break;
+ case 5:
+ *predictor = left+((upper-diag)>>1);
+ break;
+ case 6:
+ *predictor = upper+((left-diag)>>1);
+ break;
+ case 7:
+ *predictor = (left+upper)>>1;
+ break;
+ default:
+ fprintf(stderr,"Warning: Undefined PSV\n");
+ *predictor = 0;
+ }
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * QuickPredict --
+ *
+ * Calculate the predictor for sample curRowBuf[col][curComp].
+ * It does not handle the special cases at image edges, such
+ * as first row and first column of a scan. We put the special
+ * case checkings outside so that the computations in main
+ * loop can be simpler. This has enhenced the performance
+ * significantly.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor)
+ int col; /* column # of the pixel to be predicted */
+ int curComp; /* the pixel's component that is predicting */
+ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */
+ int psv; /* predictor selection value */
+ int *predictor; /* preditor value (output) */
+{
+ register int left,upper,diag,leftcol;
+
+ leftcol=col-1;
+ upper=prevRowBuf[col][curComp];
+ left=curRowBuf[leftcol][curComp];
+ diag=prevRowBuf[leftcol][curComp];
+
+ /*
+ * All predictor are calculated according to psv.
+ */
+ switch (psv) {
+ case 0:
+ *predictor = 0;
+ break;
+ case 1:
+ *predictor = left;
+ break;
+ case 2:
+ *predictor = upper;
+ break;
+ case 3:
+ *predictor = diag;
+ break;
+ case 4:
+ *predictor = left+upper-diag;
+ break;
+ case 5:
+ *predictor = left+((upper-diag)>>1);
+ break;
+ case 6:
+ *predictor = upper+((left-diag)>>1);
+ break;
+ case 7:
+ *predictor = (left+upper)>>1;
+ break;
+ default:
+ fprintf(stderr,"Warning: Undefined PSV\n");
+ *predictor = 0;
+ }
+}
+#endif /*DEBUG*/
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/predictor.h b/kernel/kls_ljpeg/ljpeg2ppm/predictor.h
new file mode 100644
index 0000000..a27b34e
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/predictor.h
@@ -0,0 +1,176 @@
+/*
+ * predictor.h --
+ *
+ * Code for predictor calculation. Its function version, predictor.c,
+ * is used in debugging compilation.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _PREDICTOR
+#define _PREDICTOR
+
+#ifndef DEBUG
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Predict --
+ *
+ * Calculate the predictor for pixel[row][col][curComp],
+ * i.e. curRowBuf[col][curComp]. It handles the all special
+ * cases at image edges, such as first row and first column
+ * of a scan.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor)\
+{ register int left,upper,diag,leftcol; \
+ \
+ leftcol=col-1; \
+ if (row==0) { \
+ \
+ /* \
+ * The predictor of first pixel is (1<<(Pr-Pt-1), and the \
+ * predictors for rest of first row are left neighbors. \
+ */ \
+ if (col==0) { \
+ *predictor = (1<<(Pr-Pt-1)); \
+ } \
+ else { \
+ *predictor = curRowBuf[leftcol][curComp]; \
+ } \
+ } \
+ else { \
+ \
+ /* \
+ * The predictors of first column are upper neighbors. \
+ * All other preditors are calculated according to psv. \
+ */ \
+ upper=prevRowBuf[col][curComp]; \
+ if (col==0) \
+ *predictor = upper; \
+ else { \
+ left=curRowBuf[leftcol][curComp]; \
+ diag=prevRowBuf[leftcol][curComp]; \
+ switch (psv) { \
+ case 0: \
+ *predictor = 0; \
+ break; \
+ case 1: \
+ *predictor = left; \
+ break; \
+ case 2: \
+ *predictor = upper; \
+ break; \
+ case 3: \
+ *predictor = diag; \
+ break; \
+ case 4: \
+ *predictor = left+upper-diag; \
+ break; \
+ case 5: \
+ *predictor = left+((upper-diag)>>1); \
+ break; \
+ case 6: \
+ *predictor = upper+((left-diag)>>1); \
+ break; \
+ case 7: \
+ *predictor = (left+upper)>>1; \
+ break; \
+ default: \
+ fprintf(stderr,"Warning: Undefined PSV\n"); \
+ *predictor = 0; \
+ } \
+ } \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * QuickPredict --
+ *
+ * Calculate the predictor for sample curRowBuf[col][curComp].
+ * It does not handle the special cases at image edges, such
+ * as first row and first column of a scan. We put the special
+ * case checkings outside so that the computations in main
+ * loop can be simpler. This has enhenced the performance
+ * significantly.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor){ \
+ register int left,upper,diag,leftcol; \
+ \
+ leftcol=col-1; \
+ upper=prevRowBuf[col][curComp]; \
+ left=curRowBuf[leftcol][curComp]; \
+ diag=prevRowBuf[leftcol][curComp]; \
+ \
+ /* \
+ * All predictor are calculated according to psv. \
+ */ \
+ switch (psv) { \
+ case 0: \
+ *predictor = 0; \
+ break; \
+ case 1: \
+ *predictor = left; \
+ break; \
+ case 2: \
+ *predictor = upper; \
+ break; \
+ case 3: \
+ *predictor = diag; \
+ break; \
+ case 4: \
+ *predictor = left+upper-diag; \
+ break; \
+ case 5: \
+ *predictor = left+((upper-diag)>>1); \
+ break; \
+ case 6: \
+ *predictor = upper+((left-diag)>>1); \
+ break; \
+ case 7: \
+ *predictor = (left+upper)>>1; \
+ break; \
+ default: \
+ fprintf(stderr,"Warning: Undefined PSV\n"); \
+ *predictor = 0; \
+ } \
+}
+
+#endif /* DEBUG */
+#endif /* _PREDICTOR */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/proto.h b/kernel/kls_ljpeg/ljpeg2ppm/proto.h
new file mode 100644
index 0000000..1188bae
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/proto.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _PROTO
+#define _PROTO
+
+#ifdef __STDC__
+# define P(s) s
+#else
+# define P(s) ()
+#endif
+
+
+/* huffc.c */
+void FlushBytes P((void ));
+void HuffEncoderInit P((CompressInfo *cPtr ));
+void HuffEncode P((CompressInfo *cPtr));
+void HuffEncoderTerm P((void ));
+
+/* huffd.c */
+void HuffDecoderInit P((DecompressInfo *dcPtr ));
+void DecodeImage P((DecompressInfo *dcPtr ));
+
+/* pnmtoljpg.c ljpgtopnm.c */
+int ReadJpegData P((char *buffer , int numBytes ));
+int WriteJpegData P((char *buffer , int numBytes));
+int main P((int argc , char **argv ));
+
+/* read.c */
+void ReadFileHeader P((DecompressInfo *dcPtr ));
+int ReadScanHeader P((DecompressInfo *dcPtr ));
+
+/* write.c */
+void WriteFileTrailer P((CompressInfo *cPtr ));
+void WriteScanHeader P((CompressInfo *cPtr ));
+void WriteFileHeader P((CompressInfo *cPtr ));
+
+/* util.c */
+int JroundUp P((int a , int b ));
+void DecoderStructInit P((DecompressInfo *dcPtr ));
+
+ /* mcu.c */
+void InitMcuTable P((int numMCU , int blocksInMCU ));
+void PrintMCU P((int blocksInMCU , MCU mcu ));
+
+#undef P
+
+#endif /* _PROTO */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/read.c b/kernel/kls_ljpeg/ljpeg2ppm/read.c
new file mode 100644
index 0000000..e4855fd
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/read.c
@@ -0,0 +1,665 @@
+/*
+ * read.c --
+ *
+ * Code for reading and processing JPEG markers. Large parts are grabbed
+ * from the IJG software, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "io.h"
+#include "proto.h"
+
+/*
+ * Enumerate all the JPEG marker codes
+ */
+typedef enum {
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JpegMarker;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Get2bytes --
+ *
+ * Get a 2-byte unsigned integer (e.g., a marker parameter length
+ * field)
+ *
+ * Results:
+ * Next two byte of input as an integer.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static Uint
+Get2bytes (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int a;
+
+ a = GetJpegChar();
+
+ return (a << 8) + GetJpegChar();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SkipVariable --
+ *
+ * Skip over an unknown or uninteresting variable-length marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed over marker.
+ *
+ *
+ *--------------------------------------------------------------
+ */
+static void
+SkipVariable (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+
+ length = Get2bytes (dcPtr) - 2;
+
+ while (length--) {
+ GetJpegChar();
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetDht --
+ *
+ * Process a DHT marker
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * A huffman table is read.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetDht (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+ Uchar bits[17];
+ Uchar huffval[256];
+ int i, index, count;
+ HuffmanTable **htblptr;
+
+ length = Get2bytes (dcPtr) - 2;
+
+ while (length) {
+ index = GetJpegChar();
+
+ bits[0] = 0;
+ count = 0;
+ for (i = 1; i <= 16; i++) {
+ bits[i] = GetJpegChar();
+ count += bits[i];
+ }
+
+ if (count > 256) {
+ fprintf (stderr, "Bogus DHT counts");
+ exit (1);
+ }
+
+ for (i = 0; i < count; i++)
+ huffval[i] = GetJpegChar();
+
+ length -= 1 + 16 + count;
+
+ if (index & 0x10) { /* AC table definition */
+ fprintf(stderr,"Huffman table for lossless JPEG is not defined.\n");
+ } else { /* DC table definition */
+ htblptr = &dcPtr->dcHuffTblPtrs[index];
+ }
+
+ if (index < 0 || index >= 4) {
+ fprintf (stderr, "Bogus DHT index %d", index);
+ exit (1);
+ }
+
+ if (*htblptr == NULL) {
+ *htblptr = (HuffmanTable *) malloc (sizeof (HuffmanTable));
+ if (*htblptr==NULL) {
+ fprintf(stderr,"Can't malloc HuffmanTable\n");
+ exit(-1);
+ }
+ }
+
+ MEMCPY((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
+ MEMCPY((*htblptr)->huffval, huffval, sizeof ((*htblptr)->huffval));
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetDri --
+ *
+ * Process a DRI marker
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Exits on error.
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetDri (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ if (Get2bytes (dcPtr) != 4) {
+ fprintf (stderr, "Bogus length in DRI");
+ exit (1);
+ }
+
+ dcPtr->restartInterval = (Ushort) Get2bytes (dcPtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetApp0 --
+ *
+ * Process an APP0 marker.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Bitstream is parsed
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetApp0 (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+
+ length = Get2bytes (dcPtr) - 2;
+ while (length-- > 0) /* skip any remaining data */
+ (void)GetJpegChar();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSof --
+ *
+ * Process a SOFn marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed
+ * Exits on error
+ * dcPtr structure is filled in
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSof (dcPtr, code)
+ DecompressInfo *dcPtr;
+ int code;
+{
+ int length;
+ short ci;
+ int c;
+ JpegComponentInfo *compptr;
+
+ length = Get2bytes (dcPtr);
+
+ dcPtr->dataPrecision = GetJpegChar();
+ dcPtr->imageHeight = Get2bytes (dcPtr);
+ dcPtr->imageWidth = Get2bytes (dcPtr);
+ dcPtr->numComponents = GetJpegChar();
+
+ /*
+ * We don't support files in which the image height is initially
+ * specified as 0 and is later redefined by DNL. As long as we
+ * have to check that, might as well have a general sanity check.
+ */
+ if ((dcPtr->imageHeight <= 0 ) ||
+ (dcPtr->imageWidth <= 0) ||
+ (dcPtr->numComponents <= 0)) {
+ fprintf (stderr, "Empty JPEG image (DNL not supported)");
+ exit(1);
+ }
+
+ if ((dcPtr->dataPrecision<MinPrecisionBits) ||
+ (dcPtr->dataPrecision>MaxPrecisionBits)) {
+ fprintf (stderr, "Unsupported JPEG data precision");
+ exit(1);
+ }
+
+ if (length != (dcPtr->numComponents * 3 + 8)) {
+ fprintf (stderr, "Bogus SOF length");
+ exit (1);
+ }
+
+ dcPtr->compInfo = (JpegComponentInfo *) malloc
+ (dcPtr->numComponents * sizeof (JpegComponentInfo));
+
+ for (ci = 0; ci < dcPtr->numComponents; ci++) {
+ compptr = &dcPtr->compInfo[ci];
+ compptr->componentIndex = ci;
+ compptr->componentId = GetJpegChar();
+ c = GetJpegChar();
+ compptr->hSampFactor = (c >> 4) & 15;
+ compptr->vSampFactor = (c) & 15;
+ (void) GetJpegChar(); /* skip Tq */
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSos --
+ *
+ * Process a SOS marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSos (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+ int i, ci, n, c, cc;
+ JpegComponentInfo *compptr;
+
+ length = Get2bytes (dcPtr);
+
+ /*
+ * Get the number of image components.
+ */
+ n = GetJpegChar();
+ dcPtr->compsInScan = n;
+ length -= 3;
+
+ if (length != (n * 2 + 3) || n < 1 || n > 4) {
+ fprintf (stderr, "Bogus SOS length");
+ exit (1);
+ }
+
+
+ for (i = 0; i < n; i++) {
+ cc = GetJpegChar();
+ c = GetJpegChar();
+ length -= 2;
+
+ for (ci = 0; ci < dcPtr->numComponents; ci++)
+ if (cc == dcPtr->compInfo[ci].componentId) {
+ break;
+ }
+
+ if (ci >= dcPtr->numComponents) {
+ fprintf (stderr, "Invalid component number in SOS");
+ exit (1);
+ }
+
+ compptr = &dcPtr->compInfo[ci];
+ dcPtr->curCompInfo[i] = compptr;
+ compptr->dcTblNo = (c >> 4) & 15;
+ }
+
+ /*
+ * Get the PSV, skip Se, and get the point transform parameter.
+ */
+ dcPtr->Ss = GetJpegChar();
+ (void)GetJpegChar();
+ c = GetJpegChar();
+ dcPtr->Pt = c & 0x0F;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSoi --
+ *
+ * Process an SOI marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSoi (dcPtr)
+ DecompressInfo *dcPtr;
+{
+
+ /*
+ * Reset all parameters that are defined to be reset by SOI
+ */
+ dcPtr->restartInterval = 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * NextMarker --
+ *
+ * Find the next JPEG marker Note that the output might not
+ * be a valid marker code but it will never be 0 or FF
+ *
+ * Results:
+ * The marker found.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static int
+NextMarker (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, nbytes;
+
+ nbytes = 0;
+ do {
+ /*
+ * skip any non-FF bytes
+ */
+ do {
+ nbytes++;
+ c = GetJpegChar();
+ } while (c != 0xFF);
+ /*
+ * skip any duplicate FFs without incrementing nbytes, since
+ * extra FFs are legal
+ */
+ do {
+ c = GetJpegChar();
+ } while (c == 0xFF);
+ } while (c == 0); /* repeat if it was a stuffed FF/00 */
+
+ return c;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ProcessTables --
+ *
+ * Scan and process JPEG markers that can appear in any order
+ * Return when an SOI, EOI, SOFn, or SOS is found
+ *
+ * Results:
+ * The marker found.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static JpegMarker
+ProcessTables (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c;
+
+ while (1) {
+ c = NextMarker (dcPtr);
+
+ switch (c) {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF2:
+ case M_SOF3:
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ case M_JPG:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ case M_SOI:
+ case M_EOI:
+ case M_SOS:
+ return ((JpegMarker)c);
+
+ case M_DHT:
+ GetDht (dcPtr);
+ break;
+
+ case M_DQT:
+ fprintf(stderr,"Not a lossless JPEG file.\n");
+ break;
+
+ case M_DRI:
+ GetDri (dcPtr);
+ break;
+
+ case M_APP0:
+ GetApp0 (dcPtr);
+ break;
+
+ case M_RST0: /* these are all parameterless */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ fprintf (stderr, "Warning: unexpected marker 0x%02x", c);
+ break;
+
+ default: /* must be DNL, DHP, EXP, APPn, JPGn, COM,
+ * or RESn */
+ SkipVariable (dcPtr);
+ break;
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadFileHeader --
+ *
+ * Initialize and read the file header (everything through
+ * the SOF marker).
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Exit on error.
+ *
+ *--------------------------------------------------------------
+ */
+void
+ReadFileHeader (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, c2;
+
+ /*
+ * Demand an SOI marker at the start of the file --- otherwise it's
+ * probably not a JPEG file at all.
+ */
+ c = GetJpegChar();
+ c2 = GetJpegChar();
+ if ((c != 0xFF) || (c2 != M_SOI)) {
+ fprintf (stderr, "Not a JPEG file\n");
+ exit (1);
+ }
+
+ GetSoi (dcPtr); /* OK, process SOI */
+
+ /*
+ * Process markers until SOF
+ */
+ c = ProcessTables (dcPtr);
+
+ switch (c) {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF3:
+ GetSof (dcPtr, c);
+ break;
+
+ default:
+ fprintf (stderr, "Unsupported SOF marker type 0x%02x", c);
+ break;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadScanHeader --
+ *
+ * Read the start of a scan (everything through the SOS marker).
+ *
+ * Results:
+ * 1 if find SOS, 0 if find EOI
+ *
+ * Side effects:
+ * Bitstream is parsed, may exit on errors.
+ *
+ *--------------------------------------------------------------
+ */
+int
+ReadScanHeader (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c;
+
+ /*
+ * Process markers until SOS or EOI
+ */
+ c = ProcessTables (dcPtr);
+
+ switch (c) {
+ case M_SOS:
+ GetSos (dcPtr);
+ return 1;
+
+ case M_EOI:
+ return 0;
+
+ default:
+ fprintf (stderr, "Unexpected marker 0x%02x", c);
+ break;
+ }
+ return 0;
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/util.c b/kernel/kls_ljpeg/ljpeg2ppm/util.c
new file mode 100644
index 0000000..d5e99cb
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/util.c
@@ -0,0 +1,297 @@
+/*
+ * util.c --
+ *
+ * Various utility routines used in the jpeg encoder/decoder. Large parts
+ * are stolen from the IJG code, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+void FreeArray2D(char **);
+void FixHuffTbl(HuffmanTable *);
+
+unsigned int bitMask[] = { 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
+ 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
+ 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
+ 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
+ 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
+ 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
+ 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
+ 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
+/*
+ *--------------------------------------------------------------
+ *
+ * JroundUp --
+ *
+ * Compute a rounded up to next multiple of b; a >= 0, b > 0
+ *
+ * Results:
+ * Rounded up value.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+int
+JroundUp (a, b)
+ int a, b;
+{
+ a += b - 1;
+ return a - (a % b);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecoderStructInit --
+ *
+ * Initalize the rest of the fields in the decompression
+ * structure.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+DecoderStructInit (dcPtr)
+ DecompressInfo *dcPtr;
+
+{
+ short ci,i;
+ JpegComponentInfo *compPtr;
+ char *buf1,*buf2;
+ int mcuSize;
+
+ /*
+ * Check sampling factor validity.
+ */
+ for (ci = 0; ci < dcPtr->numComponents; ci++) {
+ compPtr = &dcPtr->compInfo[ci];
+ if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
+ fprintf (stderr, "Error: Downsampling is not supported.\n");
+ exit(-1);
+ }
+ }
+
+ /*
+ * Prepare array describing MCU composition
+ */
+ if (dcPtr->compsInScan == 1) {
+ dcPtr->MCUmembership[0] = 0;
+ } else {
+ short lci;
+
+ if (dcPtr->compsInScan > 4) {
+ fprintf (stderr, "Too many components for interleaved scan");
+ exit (1);
+ }
+
+ for (lci = 0; lci < dcPtr->compsInScan; lci++) {
+ dcPtr->MCUmembership[lci] = lci;
+ }
+ }
+
+ /*
+ * Initialize mucROW1 and mcuROW2 which buffer two rows of
+ * pixels for predictor calculation.
+ */
+
+ if ((mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
+ fprintf(stderr,"Not enough memory for mcuROW1\n");
+ }
+ if ((mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
+ fprintf(stderr,"Not enough memory for mcuROW2\n");
+ }
+
+ mcuSize=dcPtr->compsInScan * sizeof(ComponentType);
+ if ((buf1 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
+ fprintf(stderr,"Not enough memory for buf1\n");
+ }
+ if ((buf2 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
+ fprintf(stderr,"Not enough memory for buf2\n");
+ }
+
+ for (i=0;i<dcPtr->imageWidth;i++) {
+ mcuROW1[i]=(MCU)(buf1+i*mcuSize);
+ mcuROW2[i]=(MCU)(buf2+i*mcuSize);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FixHuffTbl --
+ *
+ * Compute derived values for a Huffman table one the DHT marker
+ * has been processed. This generates both the encoding and
+ * decoding tables.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+FixHuffTbl (htbl)
+ HuffmanTable *htbl;
+{
+ int p, i, l, lastp, si;
+ char huffsize[257];
+ Ushort huffcode[257];
+ Ushort code;
+ int size;
+ int value, ll, ul;
+
+ /*
+ * Figure C.1: make table of Huffman code length for each symbol
+ * Note that this is in code-length order.
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ for (i = 1; i <= (int)htbl->bits[l]; i++)
+ huffsize[p++] = (char)l;
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+
+ /*
+ * Figure C.2: generate the codes themselves
+ * Note that this is in code-length order.
+ */
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int)huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ /*
+ * Figure C.3: generate encoding tables
+ * These are code and size indexed by symbol value
+ * Set any codeless symbols to have code length 0; this allows
+ * EmitBits to detect any attempt to emit such symbols.
+ */
+ MEMSET(htbl->ehufsi, 0, sizeof(htbl->ehufsi));
+
+ for (p = 0; p < lastp; p++) {
+ htbl->ehufco[htbl->huffval[p]] = huffcode[p];
+ htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
+ }
+
+ /*
+ * Figure F.15: generate decoding tables
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ if (htbl->bits[l]) {
+ htbl->valptr[l] = p;
+ htbl->mincode[l] = huffcode[p];
+ p += htbl->bits[l];
+ htbl->maxcode[l] = huffcode[p - 1];
+ } else {
+ htbl->maxcode[l] = -1;
+ }
+ }
+
+ /*
+ * We put in this value to ensure HuffDecode terminates.
+ */
+ htbl->maxcode[17] = 0xFFFFFL;
+
+ /*
+ * Build the numbits, value lookup tables.
+ * These table allow us to gather 8 bits from the bits stream,
+ * and immediately lookup the size and value of the huffman codes.
+ * If size is zero, it means that more than 8 bits are in the huffman
+ * code (this happens about 3-4% of the time).
+ */
+ bzero (htbl->numbits, sizeof(htbl->numbits));
+ for (p=0; p<lastp; p++) {
+ size = huffsize[p];
+ if (size <= 8) {
+ value = htbl->huffval[p];
+ code = huffcode[p];
+ ll = code << (8-size);
+ if (size < 8) {
+ ul = ll | bitMask[24+size];
+ } else {
+ ul = ll;
+ }
+ for (i=ll; i<=ul; i++) {
+ htbl->numbits[i] = size;
+ htbl->value[i] = value;
+ }
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FreeArray2D --
+ *
+ * Free the memory of a 2-D array pointed by arrayPtr.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The memory pointed by arrayPtr is freed.
+ *
+ *--------------------------------------------------------------
+ */
+void
+FreeArray2D(arrayPtr)
+ char **arrayPtr;
+{
+ free(arrayPtr[0]);
+ free(arrayPtr);
+}
diff --git a/kernel/kls_mac/Makefile.am b/kernel/kls_mac/Makefile.am
new file mode 100644
index 0000000..7dedca4
--- /dev/null
+++ b/kernel/kls_mac/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-mac2ppm
+
+pkglib_LTLIBRARIES = libkls_mac.la
+
+libkls_mac_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_mac_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_mac_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_MAC -DNETPBM_S=\"${bindir}/ksquirrel-libs-mac2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-mac2ppm.in \ No newline at end of file
diff --git a/kernel/kls_mac/fmt_codec_pnm.cpp b/kernel/kls_mac/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_mac/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_mac/fmt_codec_pnm_defs.h b/kernel/kls_mac/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_mac/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_mac/ksquirrel-libs-mac2ppm.in b/kernel/kls_mac/ksquirrel-libs-mac2ppm.in
new file mode 100644
index 0000000..9032a9f
--- /dev/null
+++ b/kernel/kls_mac/ksquirrel-libs-mac2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@MACTOPBM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_mdl/Makefile.am b/kernel/kls_mdl/Makefile.am
new file mode 100644
index 0000000..8ac900c
--- /dev/null
+++ b/kernel/kls_mdl/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_mdl.la
+
+libkls_mdl_la_SOURCES = fmt_codec_mdl.cpp fmt_codec_mdl_defs.h
+
+libkls_mdl_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_mdl_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_mdl/fmt_codec_mdl.cpp b/kernel/kls_mdl/fmt_codec_mdl.cpp
new file mode 100644
index 0000000..9a063c3
--- /dev/null
+++ b/kernel/kls_mdl/fmt_codec_mdl.cpp
@@ -0,0 +1,171 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_mdl_defs.h"
+#include "fmt_codec_mdl.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_mdl.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.2.0";
+ o->name = "HalfLife model";
+ o->filter = "*.mdl ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mdl";
+ o->pixmap = codec_mdl;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ s32 id, ver;
+
+ if(!frs.readK(&id, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&ver, sizeof(s32))) return SQE_R_BADFILE;
+
+ if(id != 0x54534449 || ver != 10)
+ return SQE_R_BADFILE;
+
+ frs.seekg(172, ios::cur);
+
+ if(!frs.readK(&numtex, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&texoff, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&texdataoff, sizeof(s32))) return SQE_R_BADFILE;
+
+ if(!numtex || !texoff || !texdataoff)
+ return SQE_R_BADFILE;
+
+ frs.seekg(texoff, ios::beg);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == numtex)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(currentImage)
+ frs.seekg(opos);
+
+ if(!frs.readK(tex.name, sizeof(tex.name))) return SQE_R_BADFILE;
+ if(!frs.readK(&tex.flags, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&tex.width, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&tex.height, sizeof(s32))) return SQE_R_BADFILE;
+ if(!frs.readK(&tex.offset, sizeof(s32))) return SQE_R_BADFILE;
+
+ opos = frs.tellg();
+
+ if(!tex.offset)
+ return SQE_R_BADFILE;
+
+ frs.seekg(tex.offset, ios::beg);
+
+ if(!frs.good())
+ return SQE_R_BADFILE;
+
+ image.w = tex.width;
+ image.h = tex.height;
+
+ fstream::pos_type pos = frs.tellg();
+
+ frs.seekg(tex.width * tex.height, ios::cur);
+
+ if(!frs.readK(pal, sizeof(RGB) * 256)) return SQE_R_BADFILE;
+
+ frs.seekg(pos);
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(8);
+ image.bpp = 8;
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u8 index;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 x = 0;x < im->w;x++)
+ {
+ if(!frs.readK(&index, sizeof(u8))) return SQE_R_BADFILE;
+
+ memcpy(scan+x, pal+index, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_mdl/fmt_codec_mdl_defs.h b/kernel/kls_mdl/fmt_codec_mdl_defs.h
new file mode 100644
index 0000000..5ca4a71
--- /dev/null
+++ b/kernel/kls_mdl/fmt_codec_mdl_defs.h
@@ -0,0 +1,35 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_mdl
+#define KSQUIRREL_CODEC_DEFS_mdl
+
+typedef struct tagTEX_HEAD
+{
+ s8 name[64];
+ s32 flags;
+ s32 width;
+ s32 height;
+ s32 offset;
+
+} TEX_HEAD;
+
+#endif
diff --git a/kernel/kls_mng/Makefile.am b/kernel/kls_mng/Makefile.am
new file mode 100644
index 0000000..b94cbcd
--- /dev/null
+++ b/kernel/kls_mng/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_mng.la
+
+libkls_mng_la_SOURCES = fmt_codec_mng.cpp fmt_codec_mng_defs.h
+
+libkls_mng_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_mng_la_LIBADD = ${SQ_LOCAL_RPATH} -lmng \ No newline at end of file
diff --git a/kernel/kls_mng/fmt_codec_mng.cpp b/kernel/kls_mng/fmt_codec_mng.cpp
new file mode 100644
index 0000000..3d72f76
--- /dev/null
+++ b/kernel/kls_mng/fmt_codec_mng.cpp
@@ -0,0 +1,372 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include <libmng.h>
+
+#include "fmt_codec_mng_defs.h"
+#include "fmt_codec_mng.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_mng.xpm"
+
+/* structure for keeping track of our mng stream inside the callbacks */
+struct mngstuff
+{
+ FILE *file; /* pointer to the file we're decoding */
+ std::string filename; /* pointer to the file's path/name */
+ fmt_codec *codec;
+};
+
+/*
+ *
+ * MNG (Multiple-image Network Graphics) is the animation extension of the popular PNG image-format.
+ * PNG (Portable Network Graphics) is an extensible file format for the lossless, portable,
+ * well-compressed storage of raster images.
+ *
+ * MNG has advanced animation features which make it very useful as a full replacement
+ * for GIF animations. These features allow animations that are impossible with GIF or
+ * result in much smaller files as GIF.
+ *
+ * As MNG builds on the same structure as PNG, it is robust, extensible and free of
+ * patents. It retains the same clever file integrity checks as in PNG.
+ *
+ * MNG also embraces the lossy JPEG image-format in a sub-format named JNG, which
+ * allows for alpha-transparency and color-correction on highly compressed (photographic) images.
+ *
+ */
+
+/* ******************************************************************** */
+/* callbacks from mngplay.c (C) Ralph Giles <giles@ashlu.bc.ca> */
+/* ******************************************************************** */
+
+/* memory allocation; data must be zeroed */
+mng_ptr mymngalloc(mng_size_t size)
+{
+ // libmng requires calloc...
+ return (mng_ptr)calloc(1, size);
+}
+
+/* memory deallocation */
+void mymngfree(mng_ptr p, mng_size_t /*size*/)
+{
+ free(p);
+}
+
+mng_bool mymngopenstream(mng_handle mng)
+{
+ mngstuff *mymng;
+
+ /* look up our stream struct */
+ mymng = (mngstuff*)mng_get_userdata(mng);
+
+ /* open the file */
+ mymng->file = fopen(mymng->filename.c_str(), "rb");
+
+ if(mymng->file == NULL)
+ return MNG_FALSE;
+
+ return MNG_TRUE;
+}
+
+mng_bool mymngprocesstext(mng_handle mng, mng_uint8 /*iType*/, mng_pchar zKeyword, mng_pchar zText,
+ mng_pchar /*zLanguage*/, mng_pchar /*zTranslation*/)
+{
+ mngstuff *mymng;
+
+ /* look up our stream struct */
+ mymng = (mngstuff *)mng_get_userdata(mng);
+
+ if(zKeyword && zText)
+ {
+ fmt_metaentry mt;
+
+ mt.group = zKeyword;
+ mt.data = zText;
+
+ mymng->codec->addmeta(mt);
+ }
+
+ return MNG_TRUE;
+}
+
+mng_bool mymngclosestream(mng_handle mng)
+{
+ mngstuff *mymng;
+
+ /* look up our stream struct */
+ mymng = (mngstuff *)mng_get_userdata(mng);
+
+ /* close the file */
+ fclose(mymng->file);
+ mymng->file = NULL;/* for safety */
+
+ mymng->filename.clear();
+
+ return MNG_TRUE;
+}
+
+/* feed data to the decoder */
+mng_bool mymngreadstream(mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread)
+{
+ mngstuff *mymng;
+
+ /* look up our stream struct */
+ mymng = (mngstuff *)mng_get_userdata(mng);
+
+ /* read the requested amount of data from the file */
+ *bytesread = fread(buffer, 1, size, mymng->file);
+
+ return MNG_TRUE;
+}
+
+/* the header's been read. set up the display stuff */
+mng_bool mymngprocessheader(mng_handle mng, mng_uint32 width, mng_uint32 height)
+{
+ mngstuff *mymng;
+
+ mymng = (mngstuff *)mng_get_userdata(mng);
+
+ mymng->codec->priv.w = width;
+
+ mymng->codec->priv.frame = new RGBA [width * height];
+
+ return (!mymng->codec->priv.frame) ? MNG_FALSE : MNG_TRUE;
+}
+
+/* return a row pointer for the decoder to fill */
+mng_ptr mymnggetcanvasline(mng_handle mng, mng_uint32 line)
+{
+ mngstuff *mymng;
+ mng_ptr row;
+
+ mymng = (mngstuff *)mng_get_userdata(mng);
+
+ row = mymng->codec->priv.frame + line * mymng->codec->priv.w;
+
+ return row;
+}
+
+/* timer */
+mng_uint32 mymnggetticks(mng_handle /*mng*/)
+{
+ return 0;
+}
+
+mng_bool mymngrefresh(mng_handle /*mng*/, mng_uint32 /*x*/, mng_uint32 /*y*/, mng_uint32 /*w*/, mng_uint32 /*h*/)
+{
+ return MNG_TRUE;
+}
+
+/* interframe delay callback */
+mng_bool mymngsettimer(mng_handle mng, mng_uint32 msecs)
+{
+ mngstuff *mymng;
+
+ mymng = (mngstuff *)mng_get_userdata(mng);
+
+ mymng->codec->priv.ms = (msecs == 1) ? 100 : msecs;
+
+ return MNG_TRUE;
+}
+
+/* ******************************************************************** */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.3.4";
+ o->name = "Multiple Network Graphics";
+
+#ifdef MNG_INCLUDE_JNG
+ o->filter = "*.mng *.jng ";
+ o->mimetype = "video/x-mng;image/x-jng";
+#else
+ o->filter = "*.mng ";
+ o->mimetype = "video/x-mng";
+#endif
+
+ o->config = "";
+ o->mime = "";
+ o->pixmap = codec_mng;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ frs.close();
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ // allocate our stream data structure
+ mymng = new mngstuff;
+
+ if(!mymng)
+ return SQE_R_NOMEMORY;
+
+ mymng->filename = file;
+ mymng->codec = this;
+ priv.frame = 0;
+ priv.ms = 10;
+
+ /* set up the mng decoder for our stream */
+ mng = mng_initialize(mymng, mymngalloc, mymngfree, MNG_NULL);
+
+ if (mng == MNG_NULL)
+ return SQE_R_NOMEMORY;
+
+ /* set the callbacks */
+ mng_setcb_openstream(mng, ::mymngopenstream);
+ mng_setcb_closestream(mng, ::mymngclosestream);
+ mng_setcb_readdata(mng, ::mymngreadstream);
+ mng_setcb_gettickcount(mng, ::mymnggetticks);
+ mng_setcb_settimer(mng, ::mymngsettimer);
+ mng_setcb_processheader(mng, ::mymngprocessheader);
+ mng_setcb_getcanvasline(mng, ::mymnggetcanvasline);
+ mng_setcb_refresh(mng, ::mymngrefresh);
+ mng_setcb_processtext(mng, ::mymngprocesstext);
+ mng_set_suspensionmode(mng, MNG_TRUE);
+ mng_set_canvasstyle(mng, MNG_CANVAS_RGBA8);
+
+ total = 0;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if((total && currentImage == total) || (!total && currentImage))
+ return SQE_NOTOK;
+
+ int myretcode;
+
+ if(!currentImage)
+ {
+ myretcode = mng_read(mng);
+
+ if(myretcode != MNG_NOERROR)
+ return SQE_R_BADFILE;
+
+ total = mng_get_totallayers(mng);
+
+ if(total > 1) total--;
+
+ myretcode = mng_display(mng);
+
+ if(myretcode != MNG_NOERROR && myretcode != MNG_NEEDTIMERWAIT)
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ myretcode = mng_display_resume(mng);
+
+ if(myretcode != MNG_NOERROR && myretcode != MNG_NEEDTIMERWAIT)
+ return SQE_R_BADFILE;
+
+ finfo.animated = true;
+ }
+
+ fmt_image image;
+
+ image.w = mng_get_imagewidth(mng);
+ image.h = mng_get_imageheight(mng);
+ image.bpp = 32;
+ image.compression = (mng_get_imagetype(mng) == MNG_IMAGETYPE_PNG) ? "Deflate method 8, 32K window" : "JPEG";
+ image.hasalpha = true;
+
+ int cc = mng_get_colortype(mng);
+
+ switch(cc)
+ {
+ case MNG_COLORTYPE_GRAY: image.colorspace = "Grayscale"; break;
+ case MNG_COLORTYPE_RGB: image.colorspace = "RGB"; break;
+ case MNG_COLORTYPE_INDEXED: image.colorspace = "Indexed"; break;
+ case MNG_COLORTYPE_GRAYA: image.colorspace = "Grayscale with alpha"; break;
+ case MNG_COLORTYPE_RGBA: image.colorspace = "RGBA"; break;
+
+ default: image.colorspace = "Unknown";
+ }
+
+ image.delay = priv.ms;
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ memcpy(scan, priv.frame+im->w*line, im->w*sizeof(RGBA));
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ mng_cleanup(&mng);
+
+ delete [] priv.frame;
+ priv.frame = 0;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_mng/fmt_codec_mng_defs.h b/kernel/kls_mng/fmt_codec_mng_defs.h
new file mode 100644
index 0000000..653b8ff
--- /dev/null
+++ b/kernel/kls_mng/fmt_codec_mng_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_mng
+#define KSQUIRREL_CODEC_DEFS_mng
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_msp/Makefile.am b/kernel/kls_msp/Makefile.am
new file mode 100644
index 0000000..27ce122
--- /dev/null
+++ b/kernel/kls_msp/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_msp.la
+
+libkls_msp_la_SOURCES = fmt_codec_msp.cpp fmt_codec_msp_defs.h
+
+libkls_msp_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_msp_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_msp/fmt_codec_msp.cpp b/kernel/kls_msp/fmt_codec_msp.cpp
new file mode 100644
index 0000000..30b09ca
--- /dev/null
+++ b/kernel/kls_msp/fmt_codec_msp.cpp
@@ -0,0 +1,228 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <vector>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_msp_defs.h"
+#include "fmt_codec_msp.h"
+
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "../xpm/codec_msp.xpm"
+
+static const RGB palmono[2] = { RGB(255,255,255), RGB(0,0,0) };
+
+/*
+ *
+ * The Microsoft Paint (MSP) image file format is used exclusively for storing
+ * black-and-white images. The vast majority of MSP files contain line drawings
+ * and clip art. MSP is used most often by Microsoft Windows applications, but
+ * may be used by MS-DOS-based programs as well. The Microsoft Paint format is
+ * apparently being replaced by the more versatile Microsoft Windows BMP format;
+ * it contains information specifically for use in the Microsoft Windows operating
+ * environment. For information on the Windows-specific use of the header information,
+ * refer to the Microsoft Paint format specification available from Microsoft.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "Microsoft Paint";
+ o->filter = "*.msp ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-msp";
+ o->pixmap = codec_msp;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+ bytes = NULL;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.readK(&msp, sizeof(msp_header)))
+ return SQE_R_BADFILE;
+
+ if(msp.key1 == MAGIC_OLD_1 || msp.key2 == MAGIC_OLD_2)
+ version = 1;
+ else if(msp.key1 == MAGIC_1 || msp.key2 == MAGIC_2)
+ version = 2;
+ else
+ return SQE_R_BADFILE;
+
+ bytes = new u8 [msp.width];
+
+ if(!bytes)
+ return SQE_R_NOMEMORY;
+
+ if(version == 2)
+ {
+ u16 map_entry;
+
+ frs.seekg(32, ios::beg);
+
+ for(s32 i = 0;i < msp.height;i++)
+ {
+ if(!frs.readK(&map_entry, sizeof(u16)))
+ return SQE_R_BADFILE;
+
+ scanmap.push_back(map_entry);
+ }
+ }
+
+ image.w = msp.width;
+ image.h = msp.height;
+ image.bpp = 1;
+ image.compression = (version == 2) ? "RLE" : "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(1);
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ RGBA rgba;
+ s32 i = 0, k = 0;
+ u8 c, count, value;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ const u16 sz = scanmap[line];
+
+ memset(bytes, 0, im->w);
+
+ while(i < sz)
+ {
+ if(!frs.readK(&c, sizeof(u8)))
+ return SQE_R_BADFILE;
+
+ i++;
+
+ if(!c)
+ {
+ if(!frs.readK(&count, sizeof(u8))) return SQE_R_BADFILE;
+ if(!frs.readK(&value, sizeof(u8))) return SQE_R_BADFILE;
+
+ i += 2;
+
+ if(count)
+ {
+ for(s32 s = 0;s < (s32)count;s++)
+ bytes[k+s] = value;
+
+ k += count;
+ }
+ }
+ else
+ {
+ if(!frs.readK(bytes+k, sizeof(u8) * c)) return SQE_R_BADFILE;
+
+ i++;
+ k += c;
+ }
+ }
+
+ s32 aa = 320;
+ for(s32 k = 0;k <= line;k++)
+ aa += scanmap[k];
+
+ s32 ind = 0;
+
+ for(i = 0;i < sz;i++)
+ {
+ fmt_utils::expandMono1Byte(bytes[i], byte);
+
+ for(s32 j = 0;j < 8 || ind < im->w;j++)
+ {
+ memcpy(scan+ind, palmono+byte[i], sizeof(RGB));
+ ind++;
+ }
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ scanmap.clear();
+
+ delete [] bytes;
+ bytes = NULL;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_msp/fmt_codec_msp_defs.h b/kernel/kls_msp/fmt_codec_msp_defs.h
new file mode 100644
index 0000000..ded5cbe
--- /dev/null
+++ b/kernel/kls_msp/fmt_codec_msp_defs.h
@@ -0,0 +1,49 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_msp
+#define KSQUIRREL_CODEC_DEFS_msp
+
+#define MAGIC_OLD_1 0x6144
+#define MAGIC_OLD_2 0x4D6E
+#define MAGIC_1 0x694C
+#define MAGIC_2 0x536E
+
+struct msp_header
+{
+ u16 key1; /* Magic number */
+ u16 key2; /* Magic number */
+ u16 width; /* Width of the bitmap in pixels */
+ u16 height; /* Height of the bitmap in pixels */
+ u16 XARBitmap; /* X Aspect ratio of the bitmap */
+ u16 YARBitmap; /* Y Aspect ratio of the bitmap */
+ u16 XARPrinter; /* X Aspect ratio of the printer */
+ u16 YARPrinter; /* Y Aspect ratio of the printer */
+ u16 printerWidth; /* Width of the printer in pixels */
+ u16 printerHeight; /* Height of the printer in pixels */
+ u16 XAspectCorr; /* X aspect correction (unused) */
+ u16 YAspectCorr; /* Y aspect correction (unused) */
+ u16 checksum; /* Checksum of previous 24 bytes */
+ u16 padding[3]; /* Unused padding */
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_mtv/Makefile.am b/kernel/kls_mtv/Makefile.am
new file mode 100644
index 0000000..fe70b54
--- /dev/null
+++ b/kernel/kls_mtv/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_mtv.la
+
+libkls_mtv_la_SOURCES = fmt_codec_mtv.cpp fmt_codec_mtv_defs.h
+
+libkls_mtv_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_mtv_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_mtv/fmt_codec_mtv.cpp b/kernel/kls_mtv/fmt_codec_mtv.cpp
new file mode 100644
index 0000000..83bfbe3
--- /dev/null
+++ b/kernel/kls_mtv/fmt_codec_mtv.cpp
@@ -0,0 +1,196 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_mtv_defs.h"
+#include "fmt_codec_mtv.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_mtv.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.1";
+ o->name = "MTV Ray tracer";
+ o->filter = "*.mtv ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mtv";
+ o->pixmap = codec_mtv;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+
+ if(!frs.getS(str, sizeof(str)))
+ return SQE_R_BADFILE;
+
+ std::stringstream ss(str);
+
+ ss >> image.w;
+ ss >> image.h;
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(24);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->passes = 1;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ s8 s[80];
+
+ snprintf(s, sizeof(s), "%d %d\n", writeimage.w, writeimage.h);
+
+ if(!fws.writeK(s, strlen(s))) return SQE_W_ERROR;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB))) return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("mtv");
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_mtv/fmt_codec_mtv_defs.h b/kernel/kls_mtv/fmt_codec_mtv_defs.h
new file mode 100644
index 0000000..4268742
--- /dev/null
+++ b/kernel/kls_mtv/fmt_codec_mtv_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_mtv
+#define KSQUIRREL_CODEC_DEFS_mtv
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_neo/Makefile.am b/kernel/kls_neo/Makefile.am
new file mode 100644
index 0000000..ceae15b
--- /dev/null
+++ b/kernel/kls_neo/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-neo2ppm
+
+pkglib_LTLIBRARIES = libkls_neo.la
+
+libkls_neo_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_neo_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_neo_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_NEO -DNETPBM_S=\"${bindir}/ksquirrel-libs-neo2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-neo2ppm.in \ No newline at end of file
diff --git a/kernel/kls_neo/fmt_codec_pnm.cpp b/kernel/kls_neo/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_neo/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_neo/fmt_codec_pnm_defs.h b/kernel/kls_neo/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_neo/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_neo/ksquirrel-libs-neo2ppm.in b/kernel/kls_neo/ksquirrel-libs-neo2ppm.in
new file mode 100644
index 0000000..6287b9b
--- /dev/null
+++ b/kernel/kls_neo/ksquirrel-libs-neo2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@NEOTOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_openexr/Makefile.am b/kernel/kls_openexr/Makefile.am
new file mode 100644
index 0000000..debce0e
--- /dev/null
+++ b/kernel/kls_openexr/Makefile.am
@@ -0,0 +1,11 @@
+CXXFLAGS = @CXXFLAGS@ -fexceptions
+
+INCLUDES = -I../include @SQ_EXR_CFLAGS@
+
+pkglib_LTLIBRARIES = libkls_openexr.la
+
+libkls_openexr_la_SOURCES = fmt_codec_openexr.cpp fmt_codec_openexr_defs.h
+
+libkls_openexr_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_openexr_la_LIBADD = @SQ_EXR_LDFLAGS@ ${SQ_LOCAL_RPATH} \ No newline at end of file
diff --git a/kernel/kls_openexr/fmt_codec_openexr.cpp b/kernel/kls_openexr/fmt_codec_openexr.cpp
new file mode 100644
index 0000000..58a9586
--- /dev/null
+++ b/kernel/kls_openexr/fmt_codec_openexr.cpp
@@ -0,0 +1,303 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <exception>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include <ImfStandardAttributes.h>
+#include <ImathBox.h>
+#include <ImfInputFile.h>
+#include <ImfBoxAttribute.h>
+#include <ImfChannelListAttribute.h>
+#include <ImfCompressionAttribute.h>
+#include <ImfFloatAttribute.h>
+#include <ImfIntAttribute.h>
+#include <ImfLineOrderAttribute.h>
+#include <ImfStringAttribute.h>
+#include <ImfVecAttribute.h>
+#include <ImfConvert.h>
+
+#include "fmt_codec_openexr_defs.h"
+#include "fmt_codec_openexr.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_openexr.xpm"
+
+RGBA RgbaToRGBA(struct Rgba);
+
+/*
+ *
+ * A high-dynamic-range image format from Industrial Light & Magic
+ * for use in digital visual effects production.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.2.1";
+ o->name = "OpenEXR";
+ o->filter = "*.exr ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-exr";
+ o->pixmap = codec_openexr;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &fl)
+{
+ frs.open(fl.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ frs.close();
+
+ currentImage = -1;
+ read_error = false;
+
+ pixels = 0;
+ file = fl;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s32 width, height;
+
+ RgbaInputFile *in = NULL;
+
+ pixels = new Array2D<Rgba>;
+
+ try
+ {
+ in = new RgbaInputFile(file.c_str());
+
+ Imath::Box2i dw = in->dataWindow();
+
+ width = dw.max.x - dw.min.x + 1;
+ height = dw.max.y - dw.min.y + 1;
+
+ pixels->resizeErase(height, width);
+
+ in->setFrameBuffer(&(*pixels)[0][0] - dw.min.x - dw.min.y * width, 1, width);
+
+ in->readPixels(dw.min.y, dw.max.y);
+ }
+ catch(const exception &e)
+ {
+ cerr << e.what() << endl;
+
+ delete in;
+
+ return SQE_R_BADFILE;
+ }
+
+ switch(in->compression())
+ {
+ case Imf::NO_COMPRESSION:
+ image.compression = "-";
+ break;
+
+ case Imf::RLE_COMPRESSION:
+ image.compression = "RLE";
+ break;
+
+ case Imf::ZIPS_COMPRESSION:
+ image.compression = "ZIPS";
+ break;
+
+ case Imf::ZIP_COMPRESSION:
+ image.compression = "ZIP";
+ break;
+
+ case Imf::PIZ_COMPRESSION:
+ image.compression = "PIZ";
+ break;
+
+ case Imf::PXR24_COMPRESSION:
+ image.compression = "PXR24";
+ break;
+
+ case Imf::NUM_COMPRESSION_METHODS:
+ image.compression = "Different methods";
+ break;
+
+ default:
+ image.compression = "Unknown";
+ }
+
+ image.colorspace = "RGBA";
+ image.bpp = 32;
+ image.w = width;
+ image.h = height;
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ delete in;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGBA rgba;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ for(s32 x = 0; x < im->w; x++)
+ {
+ rgba = RgbaToRGBA((*pixels)[line][x]);
+ memcpy(scan+x, &rgba, sizeof(RGBA));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ delete pixels;
+ pixels = 0;
+}
+
+/*
+ * This function is taken from exr plugin for KImageIO, kdelibs-3.4.0:
+ *
+ * KImageIO Routines to read (and perhaps in the future, write) images
+ * in the high dynamic range EXR format.
+ * Copyright (c) 2003, Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is distributed under the conditions of the GNU LGPL.
+ *
+ * $Id: exr.cpp,v 1.4 2004/11/22 03:48:27 mueller Exp $
+ */
+
+/*
+ * utility function
+ *
+ * this does a conversion from the ILM Half (equal to Nvidia Half)
+ * format into the normal 32 bit pixel format. Process is from the
+ * ILM code.
+ *
+ */
+
+RGBA RgbaToRGBA(struct Rgba imagePixel)
+{
+ float r,g,b,a;
+
+ // 1) Compensate for fogging by subtracting defog
+ // from the raw pixel values.
+ // Response: We work with defog of 0.0, so this is a no-op
+
+ // 2) Multiply the defogged pixel values by
+ // 2^(exposure + 2.47393).
+ // Response: We work with exposure of 0.0.
+ // (2^2.47393) is 5.55555
+ r = imagePixel.r * 5.55555;
+ g = imagePixel.g * 5.55555;
+ b = imagePixel.b * 5.55555;
+ a = imagePixel.a * 5.55555;
+
+ // 3) Values, which are now 1.0, are called "middle gray".
+ // If defog and exposure are both set to 0.0, then
+ // middle gray corresponds to a raw pixel value of 0.18.
+ // In step 6, middle gray values will be mapped to an
+ // intensity 3.5 f-stops below the display's maximum
+ // intensity.
+ // Response: no apparent content.
+
+ // 4) Apply a knee function. The knee function has two
+ // parameters, kneeLow and kneeHigh. Pixel values
+ // below 2^kneeLow are not changed by the knee
+ // function. Pixel values above kneeLow are lowered
+ // according to a logarithmic curve, such that the
+ // value 2^kneeHigh is mapped to 2^3.5 (in step 6,
+ // this value will be mapped to the the display's
+ // maximum intensity).
+ // Response: kneeLow = 0.0 (2^0.0 => 1); kneeHigh = 5.0 (2^5 =>32)
+ if (r > 1.0)
+ r = 1.0 + Imath::Math<float>::log ((r-1.0) * 0.184874 + 1) / 0.184874;
+ if (g > 1.0)
+ g = 1.0 + Imath::Math<float>::log ((g-1.0) * 0.184874 + 1) / 0.184874;
+ if (b > 1.0)
+ b = 1.0 + Imath::Math<float>::log ((b-1.0) * 0.184874 + 1) / 0.184874;
+ if (a > 1.0)
+ a = 1.0 + Imath::Math<float>::log ((a-1.0) * 0.184874 + 1) / 0.184874;
+//
+// 5) Gamma-correct the pixel values, assuming that the
+// screen's gamma is 0.4545 (or 1/2.2).
+ r = Imath::Math<float>::pow (r, 0.4545);
+ g = Imath::Math<float>::pow (g, 0.4545);
+ b = Imath::Math<float>::pow (b, 0.4545);
+ a = Imath::Math<float>::pow (a, 0.4545);
+
+// 6) Scale the values such that pixels middle gray
+// pixels are mapped to 84.66 (or 3.5 f-stops below
+// the display's maximum intensity).
+//
+// 7) Clamp the values to [0, 255].
+ return RGBA( s8 (Imath::clamp ( r * 84.66f, 0.f, 255.f ) ),
+ s8 (Imath::clamp ( g * 84.66f, 0.f, 255.f ) ),
+ s8 (Imath::clamp ( b * 84.66f, 0.f, 255.f ) ),
+ s8 (Imath::clamp ( a * 84.66f, 0.f, 255.f ) ) );
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_openexr/fmt_codec_openexr_defs.h b/kernel/kls_openexr/fmt_codec_openexr_defs.h
new file mode 100644
index 0000000..7b52b11
--- /dev/null
+++ b/kernel/kls_openexr/fmt_codec_openexr_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_openexr
+#define KSQUIRREL_CODEC_DEFS_openexr
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_pcx/Makefile.am b/kernel/kls_pcx/Makefile.am
new file mode 100644
index 0000000..5aaa5f3
--- /dev/null
+++ b/kernel/kls_pcx/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_pcx.la
+
+libkls_pcx_la_SOURCES = fmt_codec_pcx.cpp fmt_codec_pcx_defs.h
+
+libkls_pcx_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pcx_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_pcx/fmt_codec_pcx.cpp b/kernel/kls_pcx/fmt_codec_pcx.cpp
new file mode 100644
index 0000000..4a8710f
--- /dev/null
+++ b/kernel/kls_pcx/fmt_codec_pcx.cpp
@@ -0,0 +1,256 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pcx_defs.h"
+#include "fmt_codec_pcx.h"
+
+#include "../xpm/codec_pcx.xpm"
+
+/*
+ *
+ * PCX is one of the most widely used storage
+ * formats. It originated with ZSoft's MS-DOS-based
+ * PC Paintbrush, and because of this,
+ * PCX is sometimes referred to as the
+ * PC Paintbrush format. ZSoft entered into an
+ * OEM arrangement with Microsoft, which allowed
+ * Microsoft to bundle PC Paintbrush with various
+ * products, including a version called Microsoft Paintbrush for Windows;
+ * this product was distributed with every copy of Microsoft Windows
+ * sold. This distribution established the importance of
+ * PCX, not only on Intel-based
+ * MS-DOS platforms, but industry-wide.
+ *
+ */
+
+bool getrow(ifstreamK &s, u8*, int);
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.8.1";
+ o->name = "ZSoft PCX";
+ o->filter = "*.pcx ";
+ o->config = "";
+ o->mime = "\x000A[\x0002\x0003\x0004\x0005]";
+ o->mimetype = "image/x-pcx";
+ o->pixmap = codec_pcx;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ pal_entr = 0;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.readK(&pfh, sizeof(PCX_HEADER))) return SQE_R_BADFILE;
+
+ if(pfh.ID != 10 || pfh.Encoding != 1)
+ return SQE_R_BADFILE;
+
+ image.w = pfh.Xmax - pfh.Xmin + 1;
+ image.h = pfh.Ymax - pfh.Ymin + 1;
+ image.bpp = pfh.bpp * pfh.NPlanes;
+ pal_entr = 0;
+
+ if(pfh.bpp == 1)
+ {
+ pal_entr = 2;
+
+ memset(pal, 0, sizeof(RGB));
+ memset(pal+1, 255, sizeof(RGB));
+
+ }
+ else if(pfh.bpp <= 4)
+ {
+ pal_entr = 16;
+
+ memcpy(pal, pfh.Palette, 48);
+ }
+ else if(pfh.bpp == 8 && pfh.NPlanes == 1)
+ {
+ pal_entr = 256;
+
+ frs.seekg(-769, ios::end);
+
+ s8 test;
+ if(!frs.readK(&test, 1)) return SQE_R_BADFILE;
+
+ if(test != PCX_COLORMAP_SIGNATURE && test != PCX_COLORMAP_SIGNATURE_NEW)
+ return SQE_R_BADFILE;
+
+ if(!frs.readK(pal, 768)) return SQE_R_BADFILE;
+ }
+
+ frs.seekg(128, ios::beg);
+
+ TotalBytesLine = pfh.NPlanes * pfh.BytesPerLine;
+
+ image.compression = "-";
+ image.colorspace = ((pal_entr) ? "Color indexed":"RGB");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u16 i, j;
+ u8 channel[4][finfo.image[currentImage].w];
+ u8 indexes[finfo.image[currentImage].w];
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(i = 0;i < 4;i++)
+ memset(channel[i], 255, im->w);
+
+ switch(im->bpp)
+ {
+ case 1:
+ {
+ }
+ break;
+
+ case 4:
+ {
+ }
+ break;
+
+ case 8:
+ if(!getrow(frs, indexes, pfh.BytesPerLine))
+ return SQE_R_BADFILE;
+
+ for(i = 0;i < im->w;i++)
+ memcpy(scan+i, pal+indexes[i], sizeof(RGB));
+ break;
+
+ case 16:
+ {
+ }
+ break;
+
+ case 24:
+ {
+ for(j = 0;j < pfh.NPlanes;j++)
+ {
+ if(!getrow(frs, channel[j], pfh.BytesPerLine))
+ return SQE_R_BADFILE;
+ }
+
+ for(i = 0;i < im->w;i++)
+ {
+ scan[i].r = channel[0][i];
+ scan[i].g = channel[1][i];
+ scan[i].b = channel[2][i];
+ }
+ }
+ break;
+
+ default:;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+/* helper function */
+bool getrow(ifstreamK &f, u8 *pcxrow, s32 bytesperline)
+{
+ static s32 repetitionsLeft = 0;
+ static u8 c;
+ s32 bytesGenerated;
+
+ bytesGenerated = 0;
+ while(bytesGenerated < bytesperline)
+ {
+ if(repetitionsLeft > 0)
+ {
+ pcxrow[bytesGenerated++] = c;
+ --repetitionsLeft;
+ }
+ else
+ {
+ if(!f.readK(&c, 1)) return false;
+
+ if(c <= 192)
+ pcxrow[bytesGenerated++] = c;
+ else
+ {
+ repetitionsLeft = c&63;
+ if(!f.readK(&c, 1)) return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pcx/fmt_codec_pcx_defs.h b/kernel/kls_pcx/fmt_codec_pcx_defs.h
new file mode 100644
index 0000000..ba45b21
--- /dev/null
+++ b/kernel/kls_pcx/fmt_codec_pcx_defs.h
@@ -0,0 +1,48 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pcx
+#define KSQUIRREL_READ_IMAGE_pcx
+
+#define PCX_COLORMAP_SIGNATURE (0x0c)
+#define PCX_COLORMAP_SIGNATURE_NEW (0x0a)
+
+struct PCX_HEADER
+{
+ u8 ID;
+ u8 Version;
+ u8 Encoding;
+ u8 bpp;
+ u16 Xmin,Ymin,Xmax,Ymax;
+ u16 VDpi;
+ u16 HDpi;
+ u8 Palette[48];
+ u8 Reserved;
+ u8 NPlanes;
+ u16 BytesPerLine;
+ u16 PaletteInfo;
+ u16 HScreenSize;
+ u16 VScreenSize;
+ u8 Filler[54]; /* Header should be 128 byte length */
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_pi1/Makefile.am b/kernel/kls_pi1/Makefile.am
new file mode 100644
index 0000000..f4c6513
--- /dev/null
+++ b/kernel/kls_pi1/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-pi12ppm
+
+pkglib_LTLIBRARIES = libkls_pi1.la
+
+libkls_pi1_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_pi1_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pi1_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_PI1 -DNETPBM_S=\"${bindir}/ksquirrel-libs-pi12ppm\"
+
+EXTRA_DIST = ksquirrel-libs-pi12ppm.in \ No newline at end of file
diff --git a/kernel/kls_pi1/fmt_codec_pnm.cpp b/kernel/kls_pi1/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_pi1/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pi1/fmt_codec_pnm_defs.h b/kernel/kls_pi1/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_pi1/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_pi1/ksquirrel-libs-pi12ppm.in b/kernel/kls_pi1/ksquirrel-libs-pi12ppm.in
new file mode 100644
index 0000000..8d123f2
--- /dev/null
+++ b/kernel/kls_pi1/ksquirrel-libs-pi12ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@PI1TOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_pi3/Makefile.am b/kernel/kls_pi3/Makefile.am
new file mode 100644
index 0000000..abd5bb4
--- /dev/null
+++ b/kernel/kls_pi3/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-pi32ppm
+
+pkglib_LTLIBRARIES = libkls_pi3.la
+
+libkls_pi3_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_pi3_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pi3_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_PI3 -DNETPBM_S=\"${bindir}/ksquirrel-libs-pi32ppm\"
+
+EXTRA_DIST = ksquirrel-libs-pi32ppm.in \ No newline at end of file
diff --git a/kernel/kls_pi3/fmt_codec_pnm.cpp b/kernel/kls_pi3/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_pi3/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pi3/fmt_codec_pnm_defs.h b/kernel/kls_pi3/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_pi3/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_pi3/ksquirrel-libs-pi32ppm.in b/kernel/kls_pi3/ksquirrel-libs-pi32ppm.in
new file mode 100644
index 0000000..c79d0b6
--- /dev/null
+++ b/kernel/kls_pi3/ksquirrel-libs-pi32ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@PI3TOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_pict/Makefile.am b/kernel/kls_pict/Makefile.am
new file mode 100644
index 0000000..a5732e7
--- /dev/null
+++ b/kernel/kls_pict/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-pict2ppm
+
+pkglib_LTLIBRARIES = libkls_pict.la
+
+libkls_pict_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_pict_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pict_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_PICT -DNETPBM_S=\"${bindir}/ksquirrel-libs-pict2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-pict2ppm.in \ No newline at end of file
diff --git a/kernel/kls_pict/fmt_codec_pnm.cpp b/kernel/kls_pict/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..00edbfb
--- /dev/null
+++ b/kernel/kls_pict/fmt_codec_pnm.cpp
@@ -0,0 +1,1469 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pict/fmt_codec_pnm_defs.h b/kernel/kls_pict/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_pict/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_pict/ksquirrel-libs-pict2ppm.in b/kernel/kls_pict/ksquirrel-libs-pict2ppm.in
new file mode 100644
index 0000000..3074acd
--- /dev/null
+++ b/kernel/kls_pict/ksquirrel-libs-pict2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@PICTTOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_pix/Makefile.am b/kernel/kls_pix/Makefile.am
new file mode 100644
index 0000000..c26bf49
--- /dev/null
+++ b/kernel/kls_pix/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_pix.la
+
+libkls_pix_la_SOURCES = fmt_codec_pix.cpp fmt_codec_pix_defs.h
+
+libkls_pix_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pix_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_pix/fmt_codec_pix.cpp b/kernel/kls_pix/fmt_codec_pix.cpp
new file mode 100644
index 0000000..9b10298
--- /dev/null
+++ b/kernel/kls_pix/fmt_codec_pix.cpp
@@ -0,0 +1,156 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_pix_defs.h"
+#include "fmt_codec_pix.h"
+
+#include "../xpm/codec_pix.xpm"
+
+/*
+ *
+ * This format is sourced on IRIX
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "1.1.0";
+ o->name = "Irix PIX image";
+ o->filter = "*.pix ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pix";
+ o->pixmap = codec_pix;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ u16 _tmp;
+ PIX_HEADER pfh;
+
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.be_getshort(&pfh.width)) return SQE_R_BADFILE;
+ if(!frs.be_getshort(&pfh.height)) return SQE_R_BADFILE;
+
+ if(!frs.readK(&_tmp, sizeof(u16))) return SQE_R_BADFILE;
+ if(!frs.readK(&_tmp, sizeof(u16))) return SQE_R_BADFILE;
+
+ if(!frs.be_getshort(&pfh.bpp)) return SQE_R_BADFILE;
+
+ if(pfh.bpp != 24)
+ return SQE_R_BADFILE;
+
+ image.w = pfh.width;
+ image.h = pfh.height;
+ image.bpp = pfh.bpp;
+ image.compression = "RLE";
+ image.colorspace = fmt_utils::colorSpaceByBpp(24);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ s32 len = 0, i, counter = 0;
+ u8 count;
+ RGB rgb;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(im->bpp)
+ {
+ case 24:
+ do
+ {
+ if(!frs.readK(&count, 1)) return SQE_R_BADFILE;
+ len += count;
+
+ if(!frs.readK(&rgb.b, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&rgb.g, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&rgb.r, 1)) return SQE_R_BADFILE;
+
+ for(i = 0;i < count;i++)
+ memcpy(scan+counter++, &rgb, 3);
+
+ }while(len < im->w);
+ break;
+
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pix/fmt_codec_pix_defs.h b/kernel/kls_pix/fmt_codec_pix_defs.h
new file mode 100644
index 0000000..993b790
--- /dev/null
+++ b/kernel/kls_pix/fmt_codec_pix_defs.h
@@ -0,0 +1,36 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <stdlib.h>
+
+#ifndef KSQUIRREL_READ_IMAGE_pix
+#define KSQUIRREL_READ_IMAGE_pix
+
+struct PIX_HEADER
+{
+ ushort width;
+ ushort height;
+ ushort x,y; // not used
+ ushort bpp; // always 24!
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_png/Makefile.am b/kernel/kls_png/Makefile.am
new file mode 100644
index 0000000..c66c0f2
--- /dev/null
+++ b/kernel/kls_png/Makefile.am
@@ -0,0 +1,15 @@
+SUBDIRS = ksquirrel-libs-png
+
+INCLUDES = -I../include -Iksquirrel-libs-png
+
+pkglib_LTLIBRARIES = libkls_png.la
+
+libkls_png_la_SOURCES = fmt_codec_png.cpp fmt_codec_png_defs.h
+
+libkls_png_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_png_la_LIBADD = ${SQ_LOCAL_RPATH} -Lksquirrel-libs-png -lksquirrel-libs-png
+
+EXTRA_DIST = README
+
+AM_CXXFLAGS = -DCODEC_PNG \ No newline at end of file
diff --git a/kernel/kls_png/README b/kernel/kls_png/README
new file mode 100644
index 0000000..df9734d
--- /dev/null
+++ b/kernel/kls_png/README
@@ -0,0 +1,2 @@
+PNG codec uses its own libpng-1.2.20 version
+to support APNG images. \ No newline at end of file
diff --git a/kernel/kls_png/fmt_codec_png.cpp b/kernel/kls_png/fmt_codec_png.cpp
new file mode 100644
index 0000000..66c43ee
--- /dev/null
+++ b/kernel/kls_png/fmt_codec_png.cpp
@@ -0,0 +1,655 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs-png/png.h"
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_png_defs.h"
+#include "fmt_codec_png.h"
+
+#if defined CODEC_SVG || defined CODEC_DICOM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_SVG
+#include "../xpm/codec_svg.xpm"
+#elif defined CODEC_DICOM
+#include "../xpm/codec_dicom.xpm"
+#else
+#include "../xpm/codec_png.xpm"
+#endif
+
+/*
+ *
+ * PNG (pronounced "ping") is a bitmap file format used to transmit and
+ * store bitmapped images. PNG supports the capability of storing up to
+ * 16 bits (gray-scale) or 48 bits (truecolor) per pixel, and up to 16 bits
+ * of alpha data. It handles the progressive display
+ * of image data and the storage of gamma,
+ * transparency and textual information, and it uses an efficient and
+ * lossless form of data compression.
+ *
+ */
+
+inline bool MALLOC_ROWS(png_bytep **A, const int RB, const int H)
+{
+ *A = (png_bytep*)malloc(H * sizeof(png_bytep*));
+
+ if(!*A)
+ return false;
+
+ for(s32 row = 0; row < H; row++)
+ (*A)[row] = 0;
+
+ for(s32 row = 0; row < (s32)H; row++)
+ {
+ (*A)[row] = (png_bytep)malloc(RB);
+
+ if(!(*A)[row])
+ return false;
+
+ memset((*A)[row], 0, RB);
+ }
+
+ return true;
+}
+
+inline void FREE_ROWS(png_bytep **A, const int H)
+{
+ if(*A)
+ {
+ for(s32 i = 0;i < H;i++)
+ {
+ if((*A)[i])
+ free((*A)[i]);
+ }
+
+ free(*A);
+ *A = 0;
+ }
+}
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+#ifdef CODEC_SVG
+ o->version = "0.1.2";
+ o->name = "Scalable Vector Graphics";
+ o->filter = "*.svg *.svgz ";
+ o->config = std::string(SVG_UI); // SVG_UI comes from Makefile.am
+ o->mime = "";
+ o->mimetype = "image/svg+xml";
+ o->pixmap = codec_svg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DICOM
+ o->version = "1.1.3";
+ o->name = "DICOM";
+ o->filter = "*.dcm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-dicom";
+ o->pixmap = codec_dicom;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "1.1.3";
+ o->name = "Portable Network Graphics";
+ o->filter = "*.png ";
+ o->config = "";
+ o->mime = "\x0089\x0050\x004E\x0047\x000D\x000A\x001A\x000A";
+ o->mimetype = "image/png";
+ o->pixmap = codec_png;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#ifdef CODEC_ANOTHER
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_int;
+ val.iVal = 1;
+
+ m_settings["scale"] = val;
+}
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ png_ptr = 0;
+ info_ptr = 0;
+ fptr = 0;
+ frame = 0;
+ prev = 0;
+ cur = 0;
+ zerror = false;
+
+#ifdef CODEC_SVG
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("scale");
+
+ // percents / 100
+ int scale = (it == m_settings.end() || (*it).second.type != settings_value::v_int)
+ ? 1 : (*it).second.iVal;
+
+ if(scale < 1 || scale > 10)
+ scale = 1;
+
+ char z[32];
+ snprintf(z, 32, "%d", scale);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(SVG2PNG, SVG2PNG, "--binary", RSVG, "--input", file.c_str(), "--output", tmp.c_str(), "-z", z, (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DICOM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DICOM, DICOM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+ fptr = fopen(file.c_str(), "rb");
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ if((png_ptr = my_png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)) == NULL)
+ {
+ zerror = true;
+ return SQE_R_NOMEMORY;
+ }
+
+ if((info_ptr = my_png_create_info_struct(png_ptr)) == NULL)
+ {
+ zerror = true;
+ return SQE_R_NOMEMORY;
+ }
+
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ my_png_init_io(png_ptr, fptr);
+ my_png_read_info(png_ptr, info_ptr);
+ my_png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, (int*)0, (int*)0);
+
+ img.w = next_frame_width = width;
+ img.h = next_frame_height = height;
+ img.bpp = bit_depth;
+
+ if(img.bpp == 16)
+ my_png_set_strip_16(png_ptr);
+
+ if(img.bpp < 8)
+ my_png_set_packing(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_GRAY && img.bpp < 8)
+ my_png_set_gray_1_2_4_to_8(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_PALETTE)
+ my_png_set_palette_to_rgb(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ my_png_set_gray_to_rgb(png_ptr);
+
+ if(my_png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ my_png_set_tRNS_to_alpha(png_ptr);
+
+ my_png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+ number_passes = my_png_set_interlace_handling(png_ptr);
+
+ my_png_read_update_info(png_ptr, info_ptr);
+
+ finfo.animated = !!my_png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL);
+
+ frames = finfo.animated ? my_png_get_num_frames(png_ptr, info_ptr) : 1;
+
+ if(!frames) return SQE_R_BADFILE;
+
+ img.interlaced = number_passes > 1;
+ img.passes = finfo.animated ? 1 : number_passes;
+
+ if(finfo.animated)
+ {
+ if(!MALLOC_ROWS(&prev, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+
+ if(!MALLOC_ROWS(&cur, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+ }
+
+ std::string color_;
+
+ img.hasalpha = (color_type & PNG_COLOR_MASK_ALPHA);
+
+ switch((color_type & ~PNG_COLOR_MASK_ALPHA))
+ {
+ case PNG_COLOR_TYPE_RGB: color_ = "RGB"; break;
+ case PNG_COLOR_TYPE_PALETTE: color_ = "Color indexed"; break;
+ case PNG_COLOR_TYPE_GRAY: color_ = "Grayscale"; break;
+
+ default:
+ color_ = "Unknown";
+ }
+
+ if(img.hasalpha)
+ color_ += " with ALPHA";
+
+ img.compression = "Deflate method 8, 32K window";
+ img.colorspace = color_;
+ if(!finfo.animated) img.delay = 0;
+
+#ifdef PNG_TEXT_SUPPORTED
+ png_textp lines = info_ptr->text;
+
+ if(!lines || !info_ptr->num_text)
+ return SQE_OK;
+
+ for(s32 i = 0;i < info_ptr->num_text;i++)
+ {
+ fmt_metaentry mt;
+
+ mt.group = lines[i].key;
+ mt.data = lines[i].text;
+
+ addmeta(mt);
+ }
+#endif
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == frames)
+ return SQE_NOTOK;
+
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ if(finfo.animated)
+ {
+ if(currentImage)
+ {
+ if(next_frame_dispose_op == PNG_DISPOSE_OP_BACKGROUND)
+ {
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ memset(cur[j]+next_frame_x_offset*sizeof(RGBA), 0, next_frame_width * sizeof(RGBA));
+ }
+ else if(next_frame_dispose_op == PNG_DISPOSE_OP_PREVIOUS)
+ {
+ for(u32 i = 0;i < height;i++)
+ memcpy(cur[i], prev[i], width*sizeof(RGBA));
+ }
+ else // next_frame_dispose_op == PNG_DISPOSE_OP_NONE
+ {
+ }
+
+ for(u32 i = 0;i < height;i++)
+ memcpy(prev[i], cur[i], width*sizeof(RGBA));
+ }
+ else if(my_png_get_first_frame_is_hidden(png_ptr, info_ptr))
+ {
+ if(!MALLOC_ROWS(&frame, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+
+ my_png_read_frame_head(png_ptr, info_ptr);
+ my_png_read_image(png_ptr, frame);
+
+ FREE_ROWS(&frame, height);
+
+ frames--;
+
+ if(frames == 1)
+ {
+ my_png_read_frame_head(png_ptr, info_ptr);
+ finfo.animated = false;
+ img.passes = number_passes;
+ finfo.image.push_back(img);
+ return SQE_OK;
+ }
+ else if(!frames)
+ return SQE_R_BADFILE; // oops?
+ }
+
+ FREE_ROWS(&frame, next_frame_height);
+
+ my_png_read_frame_head(png_ptr, info_ptr);
+
+ if(my_png_get_valid(png_ptr, info_ptr, PNG_INFO_fcTL))
+ {
+ my_png_get_next_frame_fcTL(png_ptr, info_ptr,
+ &next_frame_width, &next_frame_height,
+ &next_frame_x_offset, &next_frame_y_offset,
+ &next_frame_delay_num, &next_frame_delay_den,
+ &next_frame_dispose_op, &next_frame_blend_op);
+ }
+ else
+ {
+ next_frame_width = width;
+ next_frame_height = height;
+ next_frame_x_offset = 0;
+ next_frame_y_offset = 0;
+ next_frame_dispose_op = PNG_DISPOSE_OP_BACKGROUND;
+ next_frame_blend_op = PNG_BLEND_OP_SOURCE;
+ }
+
+ if(!next_frame_delay_den) next_frame_delay_den = 100;
+
+ img.delay = (s32)(((double)next_frame_delay_num / next_frame_delay_den) * 1000);
+
+ if(next_frame_width + next_frame_x_offset > width || next_frame_height + next_frame_y_offset > height)
+ return SQE_R_BADFILE;
+
+ if(!MALLOC_ROWS(&frame, next_frame_width * sizeof(RGBA), next_frame_height))
+ return SQE_R_NOMEMORY;
+
+ my_png_read_image(png_ptr, frame);
+
+ // copy all pixel values including alpha
+ if(!currentImage || next_frame_blend_op == PNG_BLEND_OP_SOURCE)
+ {
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ memcpy(cur[j]+next_frame_x_offset*sizeof(RGBA), frame[i], next_frame_width * sizeof(RGBA));
+ }
+ else // over
+ {
+ RGBA *src, *dst;
+
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ {
+ src = (RGBA *)frame[i];
+ dst = (RGBA *)(cur[j]+next_frame_x_offset*sizeof(RGBA));
+ u32 k = next_frame_width;
+
+ while(k--)
+ {
+ // fully transparent foreground
+ if(src->a == 0)
+ ;
+ else if(src->a == 255 || dst->a == 0)
+ *dst = *src;
+ else // composite
+ {
+ dst->r = ((src->a * (src->r - dst->r))>>8) + dst->r;
+ dst->g = ((src->a * (src->g - dst->g))>>8) + dst->g;
+ dst->b = ((src->a * (src->b - dst->b))>>8) + dst->b;
+ //dst->a = ((src->a * (src->a - dst->a))>>8) + dst->a;
+ }
+
+ src++;
+ dst++;
+ }
+ }
+ }
+ }
+
+ finfo.image.push_back(img);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+
+ line++;
+
+ if(zerror || setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ if(finfo.animated)
+ memcpy(scan, cur[line], im->w * sizeof(RGBA));
+ else
+ my_png_read_row(png_ptr, (png_bytep)scan, png_bytep_NULL);
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(png_ptr) my_png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+
+ if(fptr) fclose(fptr);
+
+ FREE_ROWS(&frame, next_frame_height);
+ FREE_ROWS(&prev, height);
+ FREE_ROWS(&cur, height);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#ifdef CODEC_PNG
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = true;
+ opt->compression_scheme = CompressionInternal;
+ opt->compression_min = 1;
+ opt->compression_max = 9;
+ opt->compression_def = 7;
+ opt->passes = 8;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ m_png_ptr = 0;
+ m_info_ptr = 0;
+ m_fptr = 0;
+ m_zerror = false;
+
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ m_fptr = fopen(file.c_str(), "wb");
+
+ if(!m_fptr)
+ return SQE_W_NOFILE;
+
+ m_png_ptr = my_png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+
+ if(!m_png_ptr)
+ {
+ m_zerror = true;
+ return SQE_W_NOMEMORY;
+ }
+
+ m_info_ptr = my_png_create_info_struct(m_png_ptr);
+
+ if(!m_info_ptr)
+ {
+ m_zerror = true;
+ return SQE_W_NOMEMORY;
+ }
+
+ if(setjmp(png_jmpbuf(m_png_ptr)))
+ {
+ m_zerror = true;
+ return SQE_W_ERROR;
+ }
+
+ my_png_init_io(m_png_ptr, m_fptr);
+
+ my_png_set_IHDR(m_png_ptr, m_info_ptr, writeimage.w, writeimage.h, 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ ((writeopt.interlaced) ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE),
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_color_8 sig_bit;
+
+ sig_bit.red = 8;
+ sig_bit.green = 8;
+ sig_bit.blue = 8;
+ sig_bit.alpha = 8;
+
+ my_png_set_sBIT(m_png_ptr, m_info_ptr, &sig_bit);
+
+ s32 factor = (writeopt.compression_level < 1 || writeopt.compression_level > 9) ? 1 : writeopt.compression_level;
+
+ my_png_set_compression_level(m_png_ptr, factor);
+
+ my_png_write_info(m_png_ptr, m_info_ptr);
+
+ my_png_set_shift(m_png_ptr, &sig_bit);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ my_png_set_swap(m_png_ptr);
+
+ my_png_set_packswap(m_png_ptr);
+
+ my_png_set_interlace_handling(m_png_ptr);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ if(m_zerror || setjmp(png_jmpbuf(m_png_ptr)))
+ {
+ m_zerror = true;
+ return SQE_W_ERROR;
+ }
+
+ m_row_pointer = (png_bytep)scan;
+
+ my_png_write_rows(m_png_ptr, &m_row_pointer, 1);
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ if(m_png_ptr && !m_zerror) my_png_write_end(m_png_ptr, m_info_ptr);
+ if(m_png_ptr) my_png_destroy_write_struct(&m_png_ptr, &m_info_ptr);
+ if(m_fptr) fclose(m_fptr);
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("png");
+}
+
+#endif
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_png/fmt_codec_png_defs.h b/kernel/kls_png/fmt_codec_png_defs.h
new file mode 100644
index 0000000..afef4ac
--- /dev/null
+++ b/kernel/kls_png/fmt_codec_png_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_png
+#define KSQUIRREL_READ_IMAGE_png
+
+// Nothing to define at this moment :)
+
+#endif
diff --git a/kernel/kls_png/ksquirrel-libs-png/Makefile.am b/kernel/kls_png/ksquirrel-libs-png/Makefile.am
new file mode 100644
index 0000000..9f88f20
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = -I.
+
+lib_LTLIBRARIES = libksquirrel-libs-png.la
+
+libksquirrel_libs_png_la_SOURCES = png.c pngconf.h pngerror.c pnggccrd.c pngget.c png.h pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c \
+pngrutil.c pngset.c pngtrans.c pngvcrd.c pngwio.c pngwrite.c pngwtran.c pngwutil.c pnghack.h
+
+libksquirrel_libs_png_la_LIBADD = -lz -lm
diff --git a/kernel/kls_png/ksquirrel-libs-png/png.c b/kernel/kls_png/ksquirrel-libs-png/png.c
new file mode 100644
index 0000000..3e507c6
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/png.c
@@ -0,0 +1,792 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * Last changed in libpng 1.2.19 August 19, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_EXTERN
+#include "png.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_20 Your_png_h_is_not_version_1_2_20;
+
+/* Version information for C files. This had better match the version
+ * string defined in png.h. */
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
+
+#ifdef PNG_READ_SUPPORTED
+
+/* png_sig was changed to a function in version 1.0.5c */
+/* Place to hold the signature string for a PNG file. */
+PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+#endif /* PNG_READ_SUPPORTED */
+
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
+PNG_acTL;
+PNG_fcTL;
+PNG_fdAT;
+
+#ifdef PNG_READ_SUPPORTED
+/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+/* start of interlace block */
+PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+/* offset to next interlace block */
+PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+/* start of interlace block in the y direction */
+PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+/* offset to next interlace block in the y direction */
+PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+/* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+*/
+
+/* Mask to determine which pixels are valid in a pass */
+PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+
+/* Mask to determine which pixels to overwrite while displaying */
+PNG_CONST int FARDATA png_pass_dsp_mask[]
+ = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature. If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_set_sig_bytes(png_structp png_ptr, int num_bytes)
+{
+ if(png_ptr == NULL) return;
+ png_debug(1, "in png_set_sig_bytes\n");
+ if (num_bytes > 8)
+ png_error(png_ptr, "Too many bytes for PNG signature.");
+
+ png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature. We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance. Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ if (num_to_check > 8)
+ num_to_check = 8;
+ else if (num_to_check < 1)
+ return (-1);
+
+ if (start > 7)
+ return (-1);
+
+ if (start + num_to_check > 8)
+ num_to_check = 8 - start;
+
+ return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* (Obsolete) function to check signature bytes. It does not allow one
+ * to check a partial signature. This function might be removed in the
+ * future - use png_sig_cmp(). Returns true (nonzero) if the file is PNG.
+ */
+int PNGAPI
+png_check_sig(png_bytep sig, int num)
+{
+ return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
+}
+#endif
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Function to allocate memory for zlib and clear it to 0. */
+#ifdef PNG_1_0_X
+voidpf PNGAPI
+#else
+voidpf /* private */
+#endif
+png_zalloc(voidpf png_ptr, uInt items, uInt size)
+{
+ png_voidp ptr;
+ png_structp p=(png_structp)png_ptr;
+ png_uint_32 save_flags=p->flags;
+ png_uint_32 num_bytes;
+
+ if(png_ptr == NULL) return (NULL);
+ if (items > PNG_UINT_32_MAX/size)
+ {
+ png_warning (p, "Potential overflow in png_zalloc()");
+ return (NULL);
+ }
+ num_bytes = (png_uint_32)items * size;
+
+ p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+ ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
+ p->flags=save_flags;
+
+#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
+ if (ptr == NULL)
+ return ((voidpf)ptr);
+
+ if (num_bytes > (png_uint_32)0x8000L)
+ {
+ png_memset(ptr, 0, (png_size_t)0x8000L);
+ png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
+ (png_size_t)(num_bytes - (png_uint_32)0x8000L));
+ }
+ else
+ {
+ png_memset(ptr, 0, (png_size_t)num_bytes);
+ }
+#endif
+ return ((voidpf)ptr);
+}
+
+/* function to free memory for zlib */
+#ifdef PNG_1_0_X
+void PNGAPI
+#else
+void /* private */
+#endif
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+ png_free((png_structp)png_ptr, (png_voidp)ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's. Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structp png_ptr)
+{
+ png_ptr->crc = crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data. We can only pass as
+ * much data to this routine as the largest single buffer size. We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
+{
+ int need_crc = 1;
+
+ if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ if (need_crc)
+ png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
+}
+
+/* Allocate the memory for an info_struct for the application. We don't
+ * really need the png_ptr, but it could potentially be useful in the
+ * future. This should be used in favour of malloc(png_sizeof(png_info))
+ * and png_info_init() so that applications that want to use a shared
+ * libpng don't have to be recompiled if png_info changes size.
+ */
+png_infop PNGAPI
+png_create_info_struct(png_structp png_ptr)
+{
+ png_infop info_ptr;
+
+ png_debug(1, "in png_create_info_struct\n");
+ if(png_ptr == NULL) return (NULL);
+#ifdef PNG_USER_MEM_SUPPORTED
+ info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
+ png_ptr->malloc_fn, png_ptr->mem_ptr);
+#else
+ info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+#endif
+ if (info_ptr != NULL)
+ png_info_init_3(&info_ptr, png_sizeof(png_info));
+
+ return (info_ptr);
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.
+ */
+void PNGAPI
+png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
+{
+ png_infop info_ptr = NULL;
+ if(png_ptr == NULL) return;
+
+ png_debug(1, "in png_destroy_info_struct\n");
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ png_info_destroy(png_ptr, info_ptr);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
+ png_ptr->mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+}
+
+/* Initialize the info structure. This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.
+ */
+
+void PNGAPI
+png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
+{
+ png_infop info_ptr = *ptr_ptr;
+
+ if(info_ptr == NULL) return;
+
+ png_debug(1, "in png_info_init_3\n");
+
+ if(png_sizeof(png_info) > png_info_struct_size)
+ {
+ png_destroy_struct(info_ptr);
+ info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+ *ptr_ptr = info_ptr;
+ }
+
+ /* set everything to 0 */
+ png_memset(info_ptr, 0, png_sizeof (png_info));
+}
+
+#ifdef PNG_FREE_ME_SUPPORTED
+void PNGAPI
+png_data_freer(png_structp png_ptr, png_infop info_ptr,
+ int freer, png_uint_32 mask)
+{
+ png_debug(1, "in png_data_freer\n");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+ if(freer == PNG_DESTROY_WILL_FREE_DATA)
+ info_ptr->free_me |= mask;
+ else if(freer == PNG_USER_WILL_FREE_DATA)
+ info_ptr->free_me &= ~mask;
+ else
+ png_warning(png_ptr,
+ "Unknown freer parameter in png_data_freer.");
+}
+#endif
+
+void PNGAPI
+png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
+ int num)
+{
+ png_debug(1, "in png_free_data\n");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* free text item num or (if num == -1) all text items */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_TEXT)
+#endif
+{
+ if (num != -1)
+ {
+ if (info_ptr->text && info_ptr->text[num].key)
+ {
+ png_free(png_ptr, info_ptr->text[num].key);
+ info_ptr->text[num].key = NULL;
+ }
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < info_ptr->num_text; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+ png_free(png_ptr, info_ptr->text);
+ info_ptr->text = NULL;
+ info_ptr->num_text=0;
+ }
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+/* free any tRNS entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
+#endif
+{
+ png_free(png_ptr, info_ptr->trans);
+ info_ptr->valid &= ~PNG_INFO_tRNS;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+ info_ptr->trans = NULL;
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+/* free any sCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_SCAL)
+#endif
+{
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, info_ptr->scal_s_width);
+ png_free(png_ptr, info_ptr->scal_s_height);
+ info_ptr->scal_s_width = NULL;
+ info_ptr->scal_s_height = NULL;
+#endif
+ info_ptr->valid &= ~PNG_INFO_sCAL;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+/* free any pCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_PCAL)
+#endif
+{
+ png_free(png_ptr, info_ptr->pcal_purpose);
+ png_free(png_ptr, info_ptr->pcal_units);
+ info_ptr->pcal_purpose = NULL;
+ info_ptr->pcal_units = NULL;
+ if (info_ptr->pcal_params != NULL)
+ {
+ int i;
+ for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+ {
+ png_free(png_ptr, info_ptr->pcal_params[i]);
+ info_ptr->pcal_params[i]=NULL;
+ }
+ png_free(png_ptr, info_ptr->pcal_params);
+ info_ptr->pcal_params = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_pCAL;
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+/* free any iCCP entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_ICCP)
+#endif
+{
+ png_free(png_ptr, info_ptr->iccp_name);
+ png_free(png_ptr, info_ptr->iccp_profile);
+ info_ptr->iccp_name = NULL;
+ info_ptr->iccp_profile = NULL;
+ info_ptr->valid &= ~PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+/* free a given sPLT entry, or (if num == -1) all sPLT entries */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_SPLT)
+#endif
+{
+ if (num != -1)
+ {
+ if(info_ptr->splt_palettes)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[num].name);
+ png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+ info_ptr->splt_palettes[num].name = NULL;
+ info_ptr->splt_palettes[num].entries = NULL;
+ }
+ }
+ else
+ {
+ if(info_ptr->splt_palettes_num)
+ {
+ int i;
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = NULL;
+ info_ptr->splt_palettes_num = 0;
+ }
+ info_ptr->valid &= ~PNG_INFO_sPLT;
+ }
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ if(png_ptr->unknown_chunk.data)
+ {
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_UNKN)
+#endif
+{
+ if (num != -1)
+ {
+ if(info_ptr->unknown_chunks)
+ {
+ png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+ info_ptr->unknown_chunks[num].data = NULL;
+ }
+ }
+ else
+ {
+ int i;
+
+ if(info_ptr->unknown_chunks_num)
+ {
+ for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+ info_ptr->unknown_chunks_num = 0;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+/* free any hIST entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
+#endif
+{
+ png_free(png_ptr, info_ptr->hist);
+ info_ptr->hist = NULL;
+ info_ptr->valid &= ~PNG_INFO_hIST;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+/* free any PLTE entry that was internally allocated */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
+#endif
+{
+ png_zfree(png_ptr, info_ptr->palette);
+ info_ptr->palette = NULL;
+ info_ptr->valid &= ~PNG_INFO_PLTE;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+ info_ptr->num_palette = 0;
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* free any image bits attached to the info structure */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_ROWS)
+#endif
+{
+ if(info_ptr->row_pointers)
+ {
+ int row;
+ for (row = 0; row < (int)info_ptr->height; row++)
+ {
+ png_free(png_ptr, info_ptr->row_pointers[row]);
+ info_ptr->row_pointers[row]=NULL;
+ }
+ png_free(png_ptr, info_ptr->row_pointers);
+ info_ptr->row_pointers=NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_IDAT;
+}
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ if(num == -1)
+ info_ptr->free_me &= ~mask;
+ else
+ info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
+#endif
+}
+
+/* This is an internal routine to free any memory that the info struct is
+ * pointing to before re-using it or freeing the struct itself. Recall
+ * that png_free() checks for NULL pointers for us.
+ */
+void /* PRIVATE */
+png_info_destroy(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_info_destroy\n");
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->num_chunk_list)
+ {
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ png_ptr->num_chunk_list=0;
+ }
+#endif
+
+ png_info_init_3(&info_ptr, png_sizeof(png_info));
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_structp png_ptr)
+{
+ if(png_ptr == NULL) return (NULL);
+ return (png_ptr->io_ptr);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+/* Initialize the default input/output functions for the PNG file. If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io(). If you have defined
+ * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
+ * necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structp png_ptr, png_FILE_p fp)
+{
+ png_debug(1, "in png_init_io\n");
+ if(png_ptr == NULL) return;
+ png_ptr->io_ptr = (png_voidp)fp;
+}
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+png_charp PNGAPI
+png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
+{
+ static PNG_CONST char short_months[12][4] =
+ {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ if(png_ptr == NULL) return (NULL);
+ if (png_ptr->time_buffer == NULL)
+ {
+ png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
+ png_sizeof(char)));
+ }
+
+#if defined(_WIN32_WCE)
+ {
+ wchar_t time_buf[29];
+ wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+ WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
+ NULL, NULL);
+ }
+#else
+#ifdef USE_FAR_KEYWORD
+ {
+ char near_time_buf[29];
+ png_snprintf6(near_time_buf,29,"%d %s %d %02d:%02d:%02d +0000",
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+ png_memcpy(png_ptr->time_buffer, near_time_buf,
+ 29*png_sizeof(char));
+ }
+#else
+ png_snprintf6(png_ptr->time_buffer,29,"%d %s %d %02d:%02d:%02d +0000",
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+#endif
+#endif /* _WIN32_WCE */
+ return ((png_charp)png_ptr->time_buffer);
+}
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+png_charp PNGAPI
+png_get_copyright(png_structp png_ptr)
+{
+ png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
+ return ((png_charp) "\n libpng version 1.2.20 - September 8, 2007\n\
+ Copyright (c) 1998-2007 Glenn Randers-Pehrson\n\
+ Copyright (c) 1996-1997 Andreas Dilger\n\
+ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz. To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_charp PNGAPI
+png_get_libpng_ver(png_structp png_ptr)
+{
+ /* Version of *.c files used when building libpng */
+ png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
+ return ((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_ver(png_structp png_ptr)
+{
+ /* Version of *.h files used when building libpng */
+ png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
+ return ((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_version(png_structp png_ptr)
+{
+ /* Returns longer string containing both version and date */
+ png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
+ return ((png_charp) PNG_HEADER_VERSION_STRING
+#ifndef PNG_READ_SUPPORTED
+ " (NO READ SUPPORT)"
+#endif
+ "\n");
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
+{
+ /* check chunk_name and return "keep" value if it's on the list, else 0 */
+ int i;
+ png_bytep p;
+ if(png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
+ return 0;
+ p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
+ for (i = png_ptr->num_chunk_list; i; i--, p-=5)
+ if (!png_memcmp(chunk_name, p, 4))
+ return ((int)*(p+4));
+ return 0;
+}
+#endif
+
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structp png_ptr)
+{
+ if (png_ptr == NULL) return Z_STREAM_ERROR;
+ return (inflateReset(&png_ptr->zstream));
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+ /* Version of *.c files used when building libpng */
+ return((png_uint_32) PNG_LIBPNG_VER);
+}
+
+
+#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#if !defined(PNG_1_0_X)
+/* this function was added to libpng 1.2.0 */
+int PNGAPI
+png_mmx_support(void)
+{
+ /* obsolete, to be removed from libpng-1.4.0 */
+ return -1;
+}
+#endif /* PNG_1_0_X */
+#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_SIZE_T
+/* Added at libpng version 1.2.6 */
+ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
+png_size_t PNGAPI
+png_convert_size(size_t size)
+{
+ if (size > (png_size_t)-1)
+ PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
+ return ((png_size_t)size);
+}
+#endif /* PNG_SIZE_T */
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
diff --git a/kernel/kls_png/ksquirrel-libs-png/png.h b/kernel/kls_png/ksquirrel-libs-png/png.h
new file mode 100644
index 0000000..0b4873c
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/png.h
@@ -0,0 +1,3672 @@
+
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.2.20 - September 8, 2007
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Authors and maintainers:
+ * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ * libpng versions 0.97, January 1998, through 1.2.20 - September 8, 2007: Glenn
+ * See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ * Due to various miscommunications, unforeseen code incompatibilities
+ * and occasional factors outside the authors' control, version numbering
+ * on the library has not always been consistent and straightforward.
+ * The following table summarizes matters since version 0.89c, which was
+ * the first widely used release:
+ *
+ * source png.h png.h shared-lib
+ * version string int version
+ * ------- ------ ----- ----------
+ * 0.89c "1.0 beta 3" 0.89 89 1.0.89
+ * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
+ * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
+ * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
+ * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
+ * 0.97c 0.97 97 2.0.97
+ * 0.98 0.98 98 2.0.98
+ * 0.99 0.99 98 2.0.99
+ * 0.99a-m 0.99 99 2.0.99
+ * 1.00 1.00 100 2.1.0 [100 should be 10000]
+ * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
+ * 1.0.1 png.h string is 10001 2.1.0
+ * 1.0.1a-e identical to the 10002 from here on, the shared library
+ * 1.0.2 source version) 10002 is 2.V where V is the source code
+ * 1.0.2a-b 10003 version, except as noted.
+ * 1.0.3 10003
+ * 1.0.3a-d 10004
+ * 1.0.4 10004
+ * 1.0.4a-f 10005
+ * 1.0.5 (+ 2 patches) 10005
+ * 1.0.5a-d 10006
+ * 1.0.5e-r 10100 (not source compatible)
+ * 1.0.5s-v 10006 (not binary compatible)
+ * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
+ * 1.0.6d-f 10007 (still binary incompatible)
+ * 1.0.6g 10007
+ * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
+ * 1.0.6i 10007 10.6i
+ * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
+ * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
+ * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
+ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
+ * 1.0.7 1 10007 (still compatible)
+ * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
+ * 1.0.8rc1 1 10008 2.1.0.8rc1
+ * 1.0.8 1 10008 2.1.0.8
+ * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
+ * 1.0.9rc1 1 10009 2.1.0.9rc1
+ * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
+ * 1.0.9rc2 1 10009 2.1.0.9rc2
+ * 1.0.9 1 10009 2.1.0.9
+ * 1.0.10beta1 1 10010 2.1.0.10beta1
+ * 1.0.10rc1 1 10010 2.1.0.10rc1
+ * 1.0.10 1 10010 2.1.0.10
+ * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
+ * 1.0.11rc1 1 10011 2.1.0.11rc1
+ * 1.0.11 1 10011 2.1.0.11
+ * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
+ * 1.0.12rc1 2 10012 2.1.0.12rc1
+ * 1.0.12 2 10012 2.1.0.12
+ * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
+ * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
+ * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
+ * 1.2.0rc1 3 10200 3.1.2.0rc1
+ * 1.2.0 3 10200 3.1.2.0
+ * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
+ * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
+ * 1.2.1 3 10201 3.1.2.1
+ * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
+ * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
+ * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
+ * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
+ * 1.0.13 10 10013 10.so.0.1.0.13
+ * 1.2.2 12 10202 12.so.0.1.2.2
+ * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
+ * 1.2.3 12 10203 12.so.0.1.2.3
+ * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
+ * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
+ * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
+ * 1.0.14 10 10014 10.so.0.1.0.14
+ * 1.2.4 13 10204 12.so.0.1.2.4
+ * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
+ * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
+ * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
+ * 1.0.15 10 10015 10.so.0.1.0.15
+ * 1.2.5 13 10205 12.so.0.1.2.5
+ * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
+ * 1.0.16 10 10016 10.so.0.1.0.16
+ * 1.2.6 13 10206 12.so.0.1.2.6
+ * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
+ * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1
+ * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
+ * 1.0.17 10 10017 10.so.0.1.0.17
+ * 1.2.7 13 10207 12.so.0.1.2.7
+ * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
+ * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5
+ * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
+ * 1.0.18 10 10018 10.so.0.1.0.18
+ * 1.2.8 13 10208 12.so.0.1.2.8
+ * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3
+ * 1.2.9beta4-11 13 10209 12.so.0.9[.0]
+ * 1.2.9rc1 13 10209 12.so.0.9[.0]
+ * 1.2.9 13 10209 12.so.0.9[.0]
+ * 1.2.10beta1-8 13 10210 12.so.0.10[.0]
+ * 1.2.10rc1-3 13 10210 12.so.0.10[.0]
+ * 1.2.10 13 10210 12.so.0.10[.0]
+ * 1.2.11beta1-4 13 10211 12.so.0.11[.0]
+ * 1.0.19rc1-5 10 10019 10.so.0.19[.0]
+ * 1.2.11rc1-5 13 10211 12.so.0.11[.0]
+ * 1.0.19 10 10019 10.so.0.19[.0]
+ * 1.2.11 13 10211 12.so.0.11[.0]
+ * 1.0.20 10 10020 10.so.0.20[.0]
+ * 1.2.12 13 10212 12.so.0.12[.0]
+ * 1.2.13beta1 13 10213 12.so.0.13[.0]
+ * 1.0.21 10 10021 10.so.0.21[.0]
+ * 1.2.13 13 10213 12.so.0.13[.0]
+ * 1.2.14beta1-2 13 10214 12.so.0.14[.0]
+ * 1.0.22rc1 10 10022 10.so.0.22[.0]
+ * 1.2.14rc1 13 10214 12.so.0.14[.0]
+ * 1.0.22 10 10022 10.so.0.22[.0]
+ * 1.2.14 13 10214 12.so.0.14[.0]
+ * 1.2.15beta1-6 13 10215 12.so.0.15[.0]
+ * 1.0.23rc1-5 10 10023 10.so.0.23[.0]
+ * 1.2.15rc1-5 13 10215 12.so.0.15[.0]
+ * 1.0.23 10 10023 10.so.0.23[.0]
+ * 1.2.15 13 10215 12.so.0.15[.0]
+ * 1.2.16beta1-2 13 10216 12.so.0.16[.0]
+ * 1.2.16rc1 13 10216 12.so.0.16[.0]
+ * 1.0.24 10 10024 10.so.0.24[.0]
+ * 1.2.16 13 10216 12.so.0.16[.0]
+ * 1.2.17beta1-2 13 10217 12.so.0.17[.0]
+ * 1.0.25rc1 10 10025 10.so.0.25[.0]
+ * 1.2.17rc1-3 13 10217 12.so.0.17[.0]
+ * 1.0.25 10 10025 10.so.0.25[.0]
+ * 1.2.17 13 10217 12.so.0.17[.0]
+ * 1.0.26 10 10026 10.so.0.26[.0]
+ * 1.2.18 13 10218 12.so.0.18[.0]
+ * 1.2.19beta1-31 13 10219 12.so.0.19[.0]
+ * 1.0.27rc1-6 10 10027 10.so.0.27[.0]
+ * 1.2.19rc1-6 13 10219 12.so.0.19[.0]
+ * 1.0.27 10 10027 10.so.0.27[.0]
+ * 1.2.19 13 10219 12.so.0.19[.0]
+ * 1.2.20beta01-04 13 10220 12.so.0.20[.0]
+ * 1.0.28rc1-6 10 10028 10.so.0.28[.0]
+ * 1.2.20rc1-6 13 10220 12.so.0.20[.0]
+ * 1.0.28 10 10028 10.so.0.28[.0]
+ * 1.2.20 13 10220 12.so.0.20[.0]
+ *
+ * Henceforth the source version will match the shared-library major
+ * and minor numbers; the shared-library major version number will be
+ * used for changes in backward compatibility, as it is intended. The
+ * PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ * for applications, is an unsigned integer of the form xyyzz corresponding
+ * to the source version x.y.z (leading zeros in y and z). Beta versions
+ * were given the previous public release number plus a letter, until
+ * version 1.0.6j; from then on they were given the upcoming public
+ * release number plus "betaNN" or "rcN".
+ *
+ * Binary incompatibility exists only when applications make direct access
+ * to the info_ptr or png_ptr members through png.h, and the compiled
+ * application is loaded with a different version of the library.
+ *
+ * DLLNUM will change each time there are forward or backward changes
+ * in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng.txt or libpng.3 for more information. The PNG specification
+ * is available as a W3C Recommendation and as an ISO Specification,
+ * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * libpng versions 1.2.6, August 15, 2004, through 1.2.20, September 8, 2007, are
+ * Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.2.5
+ * with the following individual added to the list of Contributing Authors:
+ *
+ * Cosmin Truta
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Simon-Pierre Cadieux
+ * Eric S. Raymond
+ * Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ * There is no warranty against interference with your enjoyment of the
+ * library or against infringement. There is no warranty that our
+ * efforts or the library will fulfill any of your particular purposes
+ * or needs. This library is provided with all faults, and the entire
+ * risk of satisfactory quality, performance, accuracy, and effort is with
+ * the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Tom Lane
+ * Glenn Randers-Pehrson
+ * Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * John Bowler
+ * Kevin Bracey
+ * Sam Bushell
+ * Magnus Holmgren
+ * Greg Roelofs
+ * Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ * Andreas Dilger
+ * Dave Martindale
+ * Guy Eric Schalnat
+ * Paul Schmidt
+ * Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS". The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose. The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and
+ * must not be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from
+ * any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products. If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s",png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software. OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience. This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ * September 8, 2007
+ *
+ * Since the PNG Development group is an ad-hoc body, we can't make
+ * an official declaration.
+ *
+ * This is your unofficial assurance that libpng from version 0.71 and
+ * upward through 1.2.20 are Y2K compliant. It is my belief that earlier
+ * versions were also Y2K compliant.
+ *
+ * Libpng only has three year fields. One is a 2-byte unsigned integer
+ * that will hold years up to 65535. The other two hold the date in text
+ * format, and will hold years up to 9999.
+ *
+ * The integer is
+ * "png_uint_16 year" in png_time_struct.
+ *
+ * The strings are
+ * "png_charp time_buffer" in png_struct and
+ * "near_time_buffer", which is a local character string in png.c.
+ *
+ * There are seven time-related functions:
+ * png.c: png_convert_to_rfc_1123() in png.c
+ * (formerly png_convert_to_rfc_1152() in error)
+ * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ * png_convert_from_time_t() in pngwrite.c
+ * png_get_tIME() in pngget.c
+ * png_handle_tIME() in pngrutil.c, called in pngread.c
+ * png_set_tIME() in pngset.c
+ * png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ * All handle dates properly in a Y2K environment. The
+ * png_convert_from_time_t() function calls gmtime() to convert from system
+ * clock time, which returns (year - 1900), which we properly convert to
+ * the full 4-digit year. There is a possibility that applications using
+ * libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ * function, or that they are incorrectly passing only a 2-digit year
+ * instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ * but this is not under our control. The libpng documentation has always
+ * stated that it works with 4-digit years, and the APIs have been
+ * documented as such.
+ *
+ * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ * integer to hold the year, and can hold years as large as 65535.
+ *
+ * zlib, upon which libpng depends, is also Y2K compliant. It contains
+ * no date-related code.
+ *
+ * Glenn Randers-Pehrson
+ * libpng maintainer
+ * PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+#include "pnghack.h"
+
+/* This is not the place to learn how to use libpng. The file libpng.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build. This file is useful for looking
+ * at the actual function definitions and structure components.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.2.20"
+#define PNG_HEADER_VERSION_STRING \
+ " libpng version 1.2.20 - September 8, 2007\n"
+
+#define PNG_LIBPNG_VER_SONUM 0
+#define PNG_LIBPNG_VER_DLLNUM 13
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR 1
+#define PNG_LIBPNG_VER_MINOR 2
+#define PNG_LIBPNG_VER_RELEASE 20
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
+
+#define PNG_LIBPNG_VER_BUILD 0
+
+/* Release Status */
+#define PNG_LIBPNG_BUILD_ALPHA 1
+#define PNG_LIBPNG_BUILD_BETA 2
+#define PNG_LIBPNG_BUILD_RC 3
+#define PNG_LIBPNG_BUILD_STABLE 4
+#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
+
+/* Release-Specific Flags */
+#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
+ PNG_LIBPNG_BUILD_STABLE only */
+#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_SPECIAL */
+#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_PRIVATE */
+
+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
+
+/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000). From
+ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */
+#define PNG_LIBPNG_VER 10220 /* 1.2.20 */
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* include the compression library's header */
+#include "zlib.h"
+#endif
+
+/* include all user configurable info, including optional assembler routines */
+#include "pngconf.h"
+
+/*
+ * Added at libpng-1.2.8 */
+/* Ref MSDN: Private as priority over Special
+ * VS_FF_PRIVATEBUILD File *was not* built using standard release
+ * procedures. If this value is given, the StringFileInfo block must
+ * contain a PrivateBuild string.
+ *
+ * VS_FF_SPECIALBUILD File *was* built by the original company using
+ * standard release procedures but is a variation of the standard
+ * file of the same version number. If this value is given, the
+ * StringFileInfo block must contain a SpecialBuild string.
+ */
+
+#if defined(PNG_USER_PRIVATEBUILD)
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
+#else
+# if defined(PNG_LIBPNG_SPECIALBUILD)
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
+# else
+# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
+# endif
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This file is arranged in several sections. The first section contains
+ * structure and type definitions. The second section contains the external
+ * library functions, while the third has the internal library functions,
+ * which applications aren't expected to use directly.
+ */
+
+#ifndef PNG_NO_TYPECAST_NULL
+#define int_p_NULL (int *)NULL
+#define png_bytep_NULL (png_bytep)NULL
+#define png_bytepp_NULL (png_bytepp)NULL
+#define png_doublep_NULL (png_doublep)NULL
+#define png_error_ptr_NULL (png_error_ptr)NULL
+#define png_flush_ptr_NULL (png_flush_ptr)NULL
+#define png_free_ptr_NULL (png_free_ptr)NULL
+#define png_infopp_NULL (png_infopp)NULL
+#define png_malloc_ptr_NULL (png_malloc_ptr)NULL
+#define png_read_status_ptr_NULL (png_read_status_ptr)NULL
+#define png_rw_ptr_NULL (png_rw_ptr)NULL
+#define png_structp_NULL (png_structp)NULL
+#define png_uint_16p_NULL (png_uint_16p)NULL
+#define png_voidp_NULL (png_voidp)NULL
+#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
+#else
+#define int_p_NULL NULL
+#define png_bytep_NULL NULL
+#define png_bytepp_NULL NULL
+#define png_doublep_NULL NULL
+#define png_error_ptr_NULL NULL
+#define png_flush_ptr_NULL NULL
+#define png_free_ptr_NULL NULL
+#define png_infopp_NULL NULL
+#define png_malloc_ptr_NULL NULL
+#define png_read_status_ptr_NULL NULL
+#define png_rw_ptr_NULL NULL
+#define png_structp_NULL NULL
+#define png_uint_16p_NULL NULL
+#define png_voidp_NULL NULL
+#define png_write_status_ptr_NULL NULL
+#endif
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Version information for C files, stored in png.c. This had better match
+ * the version above.
+ */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18];
+ /* need room for 99.99.99beta99z */
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
+/* Structures to facilitate easy interlacing. See png.c for more details */
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7];
+/* This isn't currently used. If you need it, see png.c for more details.
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7];
+*/
+#endif
+
+#endif /* PNG_NO_EXTERN */
+
+/* Three color definitions. The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+ png_byte red;
+ png_byte green;
+ png_byte blue;
+} png_color;
+typedef png_color FAR * png_colorp;
+typedef png_color FAR * FAR * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+ png_byte index; /* used for palette files */
+ png_uint_16 red; /* for use in red green blue files */
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 gray; /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 FAR * png_color_16p;
+typedef png_color_16 FAR * FAR * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+ png_byte red; /* for use in red green blue files */
+ png_byte green;
+ png_byte blue;
+ png_byte gray; /* for use in grayscale files */
+ png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 FAR * png_color_8p;
+typedef png_color_8 FAR * FAR * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+ png_uint_16 red;
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 alpha;
+ png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry FAR * png_sPLT_entryp;
+typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
+
+/* When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ * occupy the LSB of their respective members, and the MSB of each member
+ * is zero-filled. The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+ png_charp name; /* palette name */
+ png_byte depth; /* depth of palette samples */
+ png_sPLT_entryp entries; /* palette entries */
+ png_int_32 nentries; /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t FAR * png_sPLT_tp;
+typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not. The "key" field
+ * points to a regular zero-terminated C string. The "text", "lang", and
+ * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
+ * However, the * structure returned by png_get_text() will always contain
+ * regular zero-terminated C strings (possibly empty), never NULL pointers,
+ * so they can be safely used in printf() and other string-handling functions.
+ */
+typedef struct png_text_struct
+{
+ int compression; /* compression value:
+ -1: tEXt, none
+ 0: zTXt, deflate
+ 1: iTXt, none
+ 2: iTXt, deflate */
+ png_charp key; /* keyword, 1-79 character description of "text" */
+ png_charp text; /* comment, may be an empty string (ie "")
+ or a NULL pointer */
+ png_size_t text_length; /* length of the text string */
+#ifdef PNG_iTXt_SUPPORTED
+ png_size_t itxt_length; /* length of the itxt string */
+ png_charp lang; /* language code, 0-79 characters
+ or a NULL pointer */
+ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
+ chars or a NULL pointer */
+#endif
+} png_text;
+typedef png_text FAR * png_textp;
+typedef png_text FAR * FAR * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE -1
+#define PNG_TEXT_COMPRESSION_zTXt 0
+#define PNG_ITXT_COMPRESSION_NONE 1
+#define PNG_ITXT_COMPRESSION_zTXt 2
+#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm. There
+ * is no portable way to convert to either of these structures, as far
+ * as I know. If you know of a portable way, send it to me. As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+ png_uint_16 year; /* full year, as in, 1995 */
+ png_byte month; /* month of year, 1 - 12 */
+ png_byte day; /* day of month, 1 - 31 */
+ png_byte hour; /* hour of day, 0 - 23 */
+ png_byte minute; /* minute of hour, 0 - 59 */
+ png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time FAR * png_timep;
+typedef png_time FAR * FAR * png_timepp;
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support. The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ */
+typedef struct png_unknown_chunk_t
+{
+ png_byte name[5];
+ png_byte *data;
+ png_size_t size;
+
+ /* libpng-using applications should NOT directly modify this byte. */
+ png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+typedef png_unknown_chunk FAR * png_unknown_chunkp;
+typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
+#endif
+
+/* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file. If you are writing the file, fill in the information
+ * you want to put into the PNG file, then call png_write_info().
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed. With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.
+ *
+ * In any case, the order of the parameters in png_info_struct should NOT
+ * be changed for as long as possible to keep compatibility with applications
+ * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng. This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions. A function to clear these members is available: see
+ * png_free_data(). The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+typedef struct png_info_struct
+{
+ /* the following are necessary for every PNG file */
+ png_uint_32 width; /* width of image in pixels (from IHDR) */
+ png_uint_32 height; /* height of image in pixels (from IHDR) */
+ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
+ png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */
+ png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
+ png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+ png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
+ png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+ png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
+ /* The following three should have been named *_method not *_type */
+ png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+ png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+ png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+ /* The following is informational only on read, and not used on writes. */
+ png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte spare_byte; /* to align the data, and for future use */
+ png_byte signature[8]; /* magic bytes read by libpng from start of file */
+
+ /* The rest of the data is optional. If you are reading, check the
+ * valid field to see if the information in these are valid. If you
+ * are writing, set the valid field to those chunks you want written,
+ * and initialize the appropriate fields below.
+ */
+
+#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+ /* The gAMA chunk describes the gamma characteristics of the system
+ * on which the image was created, normally in the range [1.0, 2.5].
+ * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+ */
+ float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+ /* GR-P, 0.96a */
+ /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
+ png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+ /* The tEXt, and zTXt chunks contain human-readable textual data in
+ * uncompressed, compressed, and optionally compressed forms, respectively.
+ * The data in "text" is an array of pointers to uncompressed,
+ * null-terminated C strings. Each chunk has a keyword that describes the
+ * textual data contained in that chunk. Keywords are not required to be
+ * unique, and the text string may be empty. Any number of text chunks may
+ * be in an image.
+ */
+ int num_text; /* number of comments read/to write */
+ int max_text; /* current size of text array */
+ png_textp text; /* array of comments read/to write */
+#endif /* PNG_TEXT_SUPPORTED */
+
+#if defined(PNG_tIME_SUPPORTED)
+ /* The tIME chunk holds the last time the displayed image data was
+ * modified. See the png_time struct for the contents of this struct.
+ */
+ png_time mod_time;
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
+ /* The sBIT chunk specifies the number of significant high-order bits
+ * in the pixel data. Values are in the range [1, bit_depth], and are
+ * only specified for the channels in the pixel data. The contents of
+ * the low-order bits is not specified. Data is valid if
+ * (valid & PNG_INFO_sBIT) is non-zero.
+ */
+ png_color_8 sig_bit; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The tRNS chunk supplies transparency data for paletted images and
+ * other image types that don't need a full alpha channel. There are
+ * "num_trans" transparency values for a paletted image, stored in the
+ * same order as the palette colors, starting from index 0. Values
+ * for the data are in the range [0, 255], ranging from fully transparent
+ * to fully opaque, respectively. For non-paletted images, there is a
+ * single color specified that should be treated as fully transparent.
+ * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+ */
+ png_bytep trans; /* transparent values for paletted image */
+ png_color_16 trans_values; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The bKGD chunk gives the suggested image background color if the
+ * display program does not have its own background color and the image
+ * is needs to composited onto a background before display. The colors
+ * in "background" are normally in the same color space/depth as the
+ * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+ */
+ png_color_16 background;
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+ /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+ * and downwards from the top-left corner of the display, page, or other
+ * application-specific co-ordinate space. See the PNG_OFFSET_ defines
+ * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
+ */
+ png_int_32 x_offset; /* x offset on page */
+ png_int_32 y_offset; /* y offset on page */
+ png_byte offset_unit_type; /* offset units type */
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+ /* The pHYs chunk gives the physical pixel density of the image for
+ * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+ * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+ */
+ png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+ png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+ /* The hIST chunk contains the relative frequency or importance of the
+ * various palette entries, so that a viewer can intelligently select a
+ * reduced-color palette, if required. Data is an array of "num_palette"
+ * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+ * is non-zero.
+ */
+ png_uint_16p hist;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+ /* The cHRM chunk describes the CIE color characteristics of the monitor
+ * on which the PNG was created. This data allows the viewer to do gamut
+ * mapping of the input image to ensure that the viewer sees the same
+ * colors in the image as the creator. Values are in the range
+ * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float x_white;
+ float y_white;
+ float x_red;
+ float y_red;
+ float x_green;
+ float y_green;
+ float x_blue;
+ float y_blue;
+#endif
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+ /* The pCAL chunk describes a transformation between the stored pixel
+ * values and original physical data values used to create the image.
+ * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+ * range given by [pcal_X0, pcal_X1], and are further transformed by a
+ * (possibly non-linear) transformation function given by "pcal_type"
+ * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
+ * defines below, and the PNG-Group's PNG extensions document for a
+ * complete description of the transformations and how they should be
+ * implemented, and for a description of the ASCII parameter strings.
+ * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+ */
+ png_charp pcal_purpose; /* pCAL chunk description string */
+ png_int_32 pcal_X0; /* minimum value */
+ png_int_32 pcal_X1; /* maximum value */
+ png_charp pcal_units; /* Latin-1 string giving physical units */
+ png_charpp pcal_params; /* ASCII strings containing parameter values */
+ png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
+ png_byte pcal_nparams; /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ /* storage for unknown chunks that the library doesn't recognize. */
+ png_unknown_chunkp unknown_chunks;
+ png_size_t unknown_chunks_num;
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+ /* iCCP chunk data. */
+ png_charp iccp_name; /* profile name */
+ png_charp iccp_profile; /* International Color Consortium profile data */
+ /* Note to maintainer: should be png_bytep */
+ png_uint_32 iccp_proflen; /* ICC profile data length */
+ png_byte iccp_compression; /* Always zero */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+ /* data on sPLT chunks (there may be more than one). */
+ png_sPLT_tp splt_palettes;
+ png_uint_32 splt_palettes_num;
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+ /* The sCAL chunk describes the actual physical dimensions of the
+ * subject matter of the graphic. The chunk contains a unit specification
+ * a byte value, and two ASCII strings representing floating-point
+ * values. The values are width and height corresponsing to one pixel
+ * in the image. This external representation is converted to double
+ * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+ */
+ png_byte scal_unit; /* unit of physical scale */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ double scal_pixel_width; /* width of one pixel */
+ double scal_pixel_height; /* height of one pixel */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_charp scal_s_width; /* string containing height */
+ png_charp scal_s_height; /* string containing width */
+#endif
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+ /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
+ /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+ png_bytepp row_pointers; /* the image bits */
+#endif
+
+#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
+ png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
+ png_fixed_point int_x_white;
+ png_fixed_point int_y_white;
+ png_fixed_point int_x_red;
+ png_fixed_point int_y_red;
+ png_fixed_point int_x_green;
+ png_fixed_point int_y_green;
+ png_fixed_point int_x_blue;
+ png_fixed_point int_y_blue;
+#endif
+
+#if defined(PNG_APNG_SUPPORTED)
+ png_uint_32 num_frames; /* including default image */
+ png_uint_32 num_plays;
+ png_uint_32 next_frame_width;
+ png_uint_32 next_frame_height;
+ png_uint_32 next_frame_x_offset;
+ png_uint_32 next_frame_y_offset;
+ png_uint_16 next_frame_delay_num;
+ png_uint_16 next_frame_delay_den;
+ png_byte next_frame_dispose_op;
+ png_byte next_frame_blend_op;
+#endif
+
+} png_info;
+
+typedef png_info FAR * png_infop;
+typedef png_info FAR * FAR * png_infopp;
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX ((png_uint_32)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
+#define PNG_MAX_UINT PNG_UINT_31_MAX
+#endif
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE 1
+#define PNG_COLOR_MASK_COLOR 2
+#define PNG_COLOR_MASK_ALPHA 4
+
+/* color types. Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type. These values should NOT be changed. */
+#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST 2 /* Not a valid value */
+
+/* These are for the oFFs chunk. These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST 2 /* Not a valid value */
+
+/* These are for the pCAL chunk. These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR 0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST 4 /* Not a valid value */
+
+/* These are for the sCAL chunk. These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER 1 /* meters per pixel */
+#define PNG_SCALE_RADIAN 2 /* radians per pixel */
+#define PNG_SCALE_LAST 3 /* Not a valid value */
+
+/* These are for the pHYs chunk. These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER 1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
+
+/* These are for the sRGB chunk. These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE 1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE 3
+#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH 79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH 256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file. The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
+#define PNG_INFO_acTL 0x10000L
+#define PNG_INFO_fcTL 0x20000L
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row. It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+ png_uint_32 width; /* width of row */
+ png_uint_32 rowbytes; /* number of bytes in row */
+ png_byte color_type; /* color type of row */
+ png_byte bit_depth; /* bit depth of row */
+ png_byte channels; /* number of channels (1, 2, 3, or 4) */
+ png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info FAR * png_row_infop;
+typedef png_row_info FAR * FAR * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own. The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions.
+ */
+typedef struct png_struct_def png_struct;
+typedef png_struct FAR * png_structp;
+
+typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
+typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
+ int));
+typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
+ int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+ png_uint_32, int));
+#if defined(PNG_APNG_SUPPORTED)
+typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp,
+ png_uint_32));
+#endif
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
+ png_row_infop, png_bytep));
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
+#endif
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
+#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
+#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
+#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
+#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
+#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
+#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
+#define PNG_TRANSFORM_BGR 0x0080 /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
+#define PNG_FLAG_MNG_FILTER_64 0x04
+#define PNG_ALL_MNG_FEATURES 0x05
+
+typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application, except to store
+ * the jmp_buf.
+ */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf jmpbuf; /* used in png_error */
+#endif
+ png_error_ptr error_fn; /* function for printing errors and aborting */
+ png_error_ptr warning_fn; /* function for printing warnings */
+ png_voidp error_ptr; /* user supplied struct for error functions */
+ png_rw_ptr write_data_fn; /* function for writing output data */
+ png_rw_ptr read_data_fn; /* function for reading input data */
+ png_voidp io_ptr; /* ptr to application struct for I/O functions */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_voidp user_transform_ptr; /* user supplied struct for user transform */
+ png_byte user_transform_depth; /* bit depth of user transformed pixels */
+ png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
+
+ png_uint_32 mode; /* tells us where we are in the PNG file */
+ png_uint_32 flags; /* flags indicating various things to libpng */
+ png_uint_32 transformations; /* which transformations to perform */
+
+ z_stream zstream; /* pointer to decompression structure (below) */
+ png_bytep zbuf; /* buffer for zlib */
+ png_size_t zbuf_size; /* size of zbuf */
+ int zlib_level; /* holds zlib compression level */
+ int zlib_method; /* holds zlib compression method */
+ int zlib_window_bits; /* holds zlib compression window bits */
+ int zlib_mem_level; /* holds zlib compression memory level */
+ int zlib_strategy; /* holds zlib compression strategy */
+
+ png_uint_32 width; /* width of image in pixels */
+ png_uint_32 height; /* height of image in pixels */
+ png_uint_32 num_rows; /* number of rows in current pass */
+ png_uint_32 usr_width; /* width of row at start of write */
+ png_uint_32 rowbytes; /* size of row in bytes */
+ png_uint_32 irowbytes; /* size of current interlaced row in bytes */
+ png_uint_32 iwidth; /* width of current interlaced row in pixels */
+ png_uint_32 row_number; /* current row in interlace pass */
+ png_bytep prev_row; /* buffer to save previous (unfiltered) row */
+ png_bytep row_buf; /* buffer to save current (unfiltered) row */
+ png_bytep sub_row; /* buffer to save "sub" row when filtering */
+ png_bytep up_row; /* buffer to save "up" row when filtering */
+ png_bytep avg_row; /* buffer to save "avg" row when filtering */
+ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
+ png_row_info row_info; /* used for transformation routines */
+
+ png_uint_32 idat_size; /* current IDAT size for read */
+ png_uint_32 crc; /* current chunk CRC value */
+ png_colorp palette; /* palette from the input file */
+ png_uint_16 num_palette; /* number of color entries in palette */
+ png_uint_16 num_trans; /* number of transparency values */
+ png_byte chunk_name[5]; /* null-terminated name of current chunk */
+ png_byte compression; /* file compression type (always 0) */
+ png_byte filter; /* file filter type (always 0) */
+ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+ png_byte pass; /* current interlace pass (0 - 6) */
+ png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
+ png_byte color_type; /* color type of file */
+ png_byte bit_depth; /* bit depth of file */
+ png_byte usr_bit_depth; /* bit depth of users row */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte channels; /* number of channels in file */
+ png_byte usr_channels; /* channels at start of write */
+ png_byte sig_bytes; /* magic bytes read/written from start of file */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+#ifdef PNG_LEGACY_SUPPORTED
+ png_byte filler; /* filler byte for pixel expansion */
+#else
+ png_uint_16 filler; /* filler bytes for pixel expansion */
+#endif
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED)
+ png_byte background_gamma_type;
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ float background_gamma;
+# endif
+ png_color_16 background; /* background color in screen gamma space */
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif
+#endif /* PNG_bKGD_SUPPORTED */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ png_flush_ptr output_flush_fn;/* Function for flushing output */
+ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
+ png_uint_32 flush_rows; /* number of rows written since last flush */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ int gamma_shift; /* number of "insignificant" bits 16-bit gamma */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float gamma; /* file gamma value */
+ float screen_gamma; /* screen gamma value (display_exponent) */
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep gamma_table; /* gamma table for 8-bit depth files */
+ png_bytep gamma_from_1; /* converts from 1.0 to screen */
+ png_bytep gamma_to_1; /* converts from file to 1.0 */
+ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
+ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+ png_color_8 sig_bit; /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ png_color_8 shift; /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep trans; /* transparency values for paletted files */
+ png_color_16 trans_values; /* transparency values for non-paletted files */
+#endif
+
+ png_read_status_ptr read_row_fn; /* called after each row is decoded */
+ png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_progressive_info_ptr info_fn; /* called after header data fully read */
+ png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */
+ png_progressive_end_ptr end_fn; /* called after image is complete */
+ png_bytep save_buffer_ptr; /* current location in save_buffer */
+ png_bytep save_buffer; /* buffer for previously read data */
+ png_bytep current_buffer_ptr; /* current location in current_buffer */
+ png_bytep current_buffer; /* buffer for recently used data */
+ png_uint_32 push_length; /* size of current input chunk */
+ png_uint_32 skip_length; /* bytes to skip in input data */
+ png_size_t save_buffer_size; /* amount of data now in save_buffer */
+ png_size_t save_buffer_max; /* total size of save_buffer */
+ png_size_t buffer_size; /* total amount of available input data */
+ png_size_t current_buffer_size; /* amount of data now in current_buffer */
+ int process_mode; /* what push library is currently doing */
+ int cur_palette; /* current push library palette index */
+
+# if defined(PNG_TEXT_SUPPORTED)
+ png_size_t current_text_size; /* current size of text input data */
+ png_size_t current_text_left; /* how much text left to read in input */
+ png_charp current_text; /* current text chunk buffer */
+ png_charp current_text_ptr; /* current location in current_text */
+# endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* for the Borland special 64K segment handler */
+ png_bytepp offset_table_ptr;
+ png_bytep offset_table;
+ png_uint_16 offset_table_number;
+ png_uint_16 offset_table_count;
+ png_uint_16 offset_table_count_free;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ png_bytep palette_lookup; /* lookup table for dithering */
+ png_bytep dither_index; /* index translation for palette files */
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
+ png_uint_16p hist; /* histogram */
+#endif
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_byte heuristic_method; /* heuristic for row filter selection */
+ png_byte num_prev_filters; /* number of weights for previous rows */
+ png_bytep prev_filters; /* filter type(s) of previous row(s) */
+ png_uint_16p filter_weights; /* weight(s) for previous line(s) */
+ png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
+ png_uint_16p filter_costs; /* relative filter calculation cost */
+ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ png_charp time_buffer; /* String to hold RFC 1123 time text */
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+ png_voidp user_chunk_ptr;
+ png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ int num_chunk_list;
+ png_bytep chunk_list;
+#endif
+
+/* New members added in libpng-1.0.3 */
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ png_byte rgb_to_gray_status;
+ /* These were changed from png_byte in libpng-1.0.6 */
+ png_uint_16 rgb_to_gray_red_coeff;
+ png_uint_16 rgb_to_gray_green_coeff;
+ png_uint_16 rgb_to_gray_blue_coeff;
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
+ defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* changed from png_byte to png_uint_32 at version 1.2.0 */
+#ifdef PNG_1_0_X
+ png_byte mng_features_permitted;
+#else
+ png_uint_32 mng_features_permitted;
+#endif /* PNG_1_0_X */
+#endif
+
+/* New member added in libpng-1.0.7 */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_fixed_point int_gamma;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ png_byte filter_type;
+#endif
+
+#if defined(PNG_1_0_X)
+/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
+ png_uint_32 row_buf_size;
+#endif
+
+/* New members added in libpng-1.2.0 */
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+# if !defined(PNG_1_0_X)
+# if defined(PNG_MMX_CODE_SUPPORTED)
+ png_byte mmx_bitdepth_threshold;
+ png_uint_32 mmx_rowbytes_threshold;
+# endif
+ png_uint_32 asm_flags;
+# endif
+#endif
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_voidp mem_ptr; /* user supplied struct for mem functions */
+ png_malloc_ptr malloc_fn; /* function for allocating memory */
+ png_free_ptr free_fn; /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+ png_bytep dither_sort; /* working sort array */
+ png_bytep index_to_palette; /* where the original index currently is */
+ /* in the palette */
+ png_bytep palette_to_index; /* which original index points to this */
+ /* palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+ png_byte compression_type;
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_uint_32 user_width_max;
+ png_uint_32 user_height_max;
+#endif
+
+#if defined(PNG_APNG_SUPPORTED)
+ png_uint_32 apng_flags;
+ png_uint_32 next_seq_num; /* next fcTL/fdAT chunk sequence number */
+ png_uint_32 first_frame_width;
+ png_uint_32 first_frame_height;
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ png_uint_32 num_frames_read; /* incremented after all image data of */
+ /* a frame is read */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
+ png_progressive_frame_ptr frame_end_fn; /* frame data read callback */
+#endif
+#endif
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ png_uint_32 num_frames_to_write;
+ png_uint_32 num_frames_written;
+#endif
+#endif
+
+/* For png_struct.apng_flags: */
+#define PNG_FIRST_FRAME_HIDDEN 0x0001
+
+/* dispose_op flags from inside fcTL */
+#define PNG_DISPOSE_OP_NONE 0x00
+#define PNG_DISPOSE_OP_BACKGROUND 0x01
+#define PNG_DISPOSE_OP_PREVIOUS 0x02
+
+/* blend_op flags from inside fcTL */
+#define PNG_BLEND_OP_SOURCE 0x00
+#define PNG_BLEND_OP_OVER 0x01
+
+/* New member added in libpng-1.0.25 and 1.2.17 */
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ /* storage for unknown chunk that the library doesn't recognize. */
+ png_unknown_chunk unknown_chunk;
+#endif
+};
+
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef png_structp version_1_2_20;
+
+typedef png_struct FAR * FAR * png_structpp;
+
+/* Here are the function definitions most commonly used. This is not
+ * the place to find out how to use libpng. See libpng.txt for the
+ * full explanation, see example.c for the summary. This just provides
+ * a simple one line description of the use of each function.
+ */
+
+/* Returns the version number of the library */
+extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
+ int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise. Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
+ png_size_t num_to_check));
+
+/* Simple signature checking function. This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+extern PNG_EXPORT(png_structp,png_create_read_struct)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn));
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+extern PNG_EXPORT(png_structp,png_create_write_struct)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn));
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
+ PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(void,png_set_compression_buffer_size)
+ PNGARG((png_structp png_ptr, png_uint_32 size));
+#endif
+
+/* Reset the compression stream */
+extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_structp,png_create_read_struct_2)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+extern PNG_EXPORT(png_structp,png_create_write_struct_2)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+#endif
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+ png_bytep chunk_name, png_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
+ png_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
+
+/* Allocate and initialize the info structure */
+extern PNG_EXPORT(png_infop,png_create_info_struct)
+ PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
+ png_size_t png_info_struct_size));
+
+/* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read the information before the actual image data. */
+extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+ PNGARG((png_structp png_ptr, png_timep ptime));
+#endif
+
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* convert from a struct tm to png_time */
+extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+ struct tm FAR * ttime));
+
+/* convert from time_t to png_time. Uses gmtime() */
+extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
+ time_t ttime));
+#endif /* PNG_WRITE_tIME_SUPPORTED */
+#endif /* _WIN32_WCE */
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+#if !defined(PNG_1_0_X)
+extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp
+ png_ptr));
+#endif
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated */
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
+#endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* Expand the grayscale to 24-bit RGB if necessary. */
+extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* Reduce RGB to grayscale. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
+ int error_action, double red, double green ));
+#endif
+extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
+ int error_action, png_fixed_point red, png_fixed_point green ));
+extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
+ png_ptr));
+#endif
+
+extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+ png_colorp palette));
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
+ png_uint_32 filler, int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#define PNG_FILLER_BEFORE 0
+#define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+#if !defined(PNG_1_0_X)
+extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
+ png_uint_32 filler, int flags));
+#endif
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
+ png_color_8p true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing. Returns the number of passes. */
+extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Handle alpha and tRNS by replacing with a background color. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
+ png_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma));
+#endif
+#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#define PNG_BACKGROUND_GAMMA_SCREEN 1
+#define PNG_BACKGROUND_GAMMA_FILE 2
+#define PNG_BACKGROUND_GAMMA_UNIQUE 3
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip the second byte of information from a 16-bit depth file. */
+extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Turn on dithering, and reduce the palette to the number of colors available. */
+extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
+ png_colorp palette, int num_palette, int maximum_colors,
+ png_uint_16p histogram, int full_dither));
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Handle gamma correction. Screen_gamma=(display_exponent) */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
+ double screen_gamma, double default_file_gamma));
+#endif
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+/* Deprecated and will be removed. Use png_permit_mng_features() instead. */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+ int empty_plte_permitted));
+#endif
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set how many lines between output flushes - 0 for no flushing */
+extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
+#endif
+
+/* optional update palette with requested transformations */
+extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
+
+/* optional call to update the users info structure */
+extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read one or more rows of image data. */
+extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+ png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read a row of data. */
+extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+ png_bytep row,
+ png_bytep display_row));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read the whole image into memory at once. */
+extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+ png_bytepp image));
+#endif
+
+/* write a row of image data */
+extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
+ png_bytep row));
+
+/* write a few rows of image data */
+extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
+ png_bytepp row, png_uint_32 num_rows));
+
+/* write the image data */
+extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
+ png_bytepp image));
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr,
+ png_infop png_info, png_bytepp row_pointers,
+ png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
+ png_byte blend_op));
+
+extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr,
+ png_infop png_info));
+#endif
+
+/* writes the end of the PNG file. */
+extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read the end of the PNG file. */
+extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+/* free any memory associated with the png_info_struct */
+extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
+ png_infopp info_ptr_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
+ png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* free all memory used by the read (old method - NOT DLL EXPORTED) */
+extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_infop end_info_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_write_struct)
+ PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+
+/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy PNGARG((png_structp png_ptr));
+
+/* set the libpng method of handling chunk CRC errors */
+extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+ int crit_action, int ancil_action));
+
+/* Values for png_set_crc_action() to say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein. Note that it is impossible to "discard" data in a critical
+ * chunk. For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard. These values should NOT be changed.
+ *
+ * value action:critical action:ancillary
+ */
+#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
+#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
+#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
+#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
+#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
+#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib. These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them. See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* set the filtering method(s) used by libpng. Currently, the only valid
+ * value for "method" is 0.
+ */
+extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
+ int filters));
+
+/* Flags for png_set_filter() to say which filters to use. The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS 0x00
+#define PNG_FILTER_NONE 0x08
+#define PNG_FILTER_SUB 0x10
+#define PNG_FILTER_UP 0x20
+#define PNG_FILTER_AVG 0x40
+#define PNG_FILTER_PAETH 0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+ PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE 0
+#define PNG_FILTER_VALUE_SUB 1
+#define PNG_FILTER_VALUE_UP 2
+#define PNG_FILTER_VALUE_AVG 3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST 5
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows. Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters. This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified. Weights have no influence on
+ * the selection of the first row filter. Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type. Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs. There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs. Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found. If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
+ int heuristic_method, int num_weights, png_doublep filter_weights,
+ png_doublep filter_costs));
+#endif
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection. These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
+
+/* Set the library compression level. Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression). Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations. In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
+ int level));
+
+extern PNG_EXPORT(void,png_set_compression_mem_level)
+ PNGARG((png_structp png_ptr, int mem_level));
+
+extern PNG_EXPORT(void,png_set_compression_strategy)
+ PNGARG((png_structp png_ptr, int strategy));
+
+extern PNG_EXPORT(void,png_set_compression_window_bits)
+ PNGARG((png_structp png_ptr, int window_bits));
+
+extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
+ int method));
+
+/* These next functions are called for input/output, memory, and error
+ * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf(). These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn(). See libpng.txt for
+ * more information.
+ */
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the input/output for the PNG file to the default functions. */
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions. If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling. If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ */
+extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+ png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
+ png_voidp io_ptr, png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
+ png_read_status_ptr read_row_fn));
+
+extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
+ png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+ png_ptr, png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+ png_ptr, png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+ png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+ int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+ PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
+ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
+ png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
+ png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn));
+#if defined(PNG_READ_APNG_SUPPORTED)
+extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp png_ptr,
+ png_progressive_frame_ptr frame_info_fn,
+ png_progressive_frame_ptr frame_end_fn));
+#endif
+
+/* returns the user pointer associated with the push read functions */
+extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+ PNGARG((png_structp png_ptr));
+
+/* function to be called when data becomes available */
+extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* function that combines rows. Not very much different than the
+ * png_combine_row() call. Is this even used?????
+ */
+extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
+ png_bytep old_row, png_bytep new_row));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+
+#if defined(PNG_1_0_X)
+# define png_malloc_warn png_malloc
+#else
+/* Added at libpng version 1.2.4 */
+extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+#endif
+
+/* frees a pointer allocated by png_malloc() */
+extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+
+#if defined(PNG_1_0_X)
+/* Function to allocate memory for zlib. */
+extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
+ uInt size));
+
+/* Function to free memory for zlib */
+extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
+#endif
+
+/* Free data that was allocated internally */
+extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 free_me, int num));
+#ifdef PNG_FREE_ME_SUPPORTED
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application */
+extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int freer, png_uint_32 mask));
+#endif
+/* assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_UNKN 0x0200
+#define PNG_FREE_LIST 0x0400
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL 0x7fff
+#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
+ png_voidp ptr));
+#endif
+
+extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
+ png_voidp s1, png_voidp s2, png_uint_32 size));
+
+extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
+ png_voidp s1, int value, png_uint_32 size));
+
+#if defined(USE_FAR_KEYWORD) /* memory model conversion function */
+extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+ int check));
+#endif /* USE_FAR_KEYWORD */
+
+#ifndef PNG_NO_ERROR_TEXT
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+ png_const_charp error_message));
+
+/* The same, but the chunk name is prepended to the error string. */
+extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
+ png_const_charp error_message));
+#else
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr));
+#endif
+
+#ifndef PNG_NO_WARNINGS
+/* Non-fatal error in libpng. Can continue, but may have a problem. */
+extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+
+#ifdef PNG_READ_SUPPORTED
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_NO_WARNINGS */
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored. The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+returned from png_read_png(). */
+extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+/* Set row_pointers, which is an array of pointers to scanlines for use
+by png_write_png(). */
+extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image height in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image bit_depth. */
+extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image color_type. */
+extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image filter_type. */
+extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image interlace_type. */
+extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image compression_type. */
+extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+#endif
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+/* Returns pointer to signature string read from PNG header */
+extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_bKGD_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_16p *background));
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED)
+extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_16p background));
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double *white_x, double *white_y, double *red_x,
+ double *red_y, double *green_x, double *green_y, double *blue_x,
+ double *blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
+ *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+ png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
+ *int_blue_x, png_fixed_point *int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double white_x, double white_y, double red_x,
+ double red_y, double green_x, double green_y, double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double *file_gamma));
+#endif
+extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point *int_file_gamma));
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double file_gamma));
+#endif
+extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point int_file_gamma));
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_16p *hist));
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_16p hist));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
+ int *bit_depth, int *color_type, int *interlace_method,
+ int *compression_method, int *filter_method));
+
+extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_method, int compression_method,
+ int filter_method));
+
+#if defined(PNG_oFFs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+ int *unit_type));
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+ int unit_type));
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+ int *type, int *nparams, png_charp *units, png_charpp *params));
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
+ int type, int nparams, png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_colorp *palette, int *num_palette));
+
+extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_colorp palette, int num_palette));
+
+#if defined(PNG_sBIT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_8p *sig_bit));
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_8p sig_bit));
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *intent));
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int intent));
+extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int intent));
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charpp name, int *compression_type,
+ png_charpp profile, png_uint_32 *proflen));
+ /* Note to maintainer: profile should be png_bytepp */
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp name, int compression_type,
+ png_charp profile, png_uint_32 proflen));
+ /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tpp entries));
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tp entries, int nentries));
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* png_get_text also returns the number of text chunks in *num_text */
+extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/*
+ * Note while png_set_text() will accept a structure whose text,
+ * language, and translated keywords are NULL pointers, the structure
+ * returned by png_get_text will always contain regular
+ * zero-terminated C strings. They might be empty strings but
+ * they will never be NULL pointers.
+ */
+
+#if defined(PNG_TEXT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_timep *mod_time));
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_timep mod_time));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep *trans, int *num_trans,
+ png_color_16p *trans_values));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep trans, int num_trans,
+ png_color_16p trans_values));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *unit, double *width, double *height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED */
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#if defined(PNG_APNG_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
+extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
+extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_num_plays)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+
+extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL)
+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
+ png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
+ png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
+ png_byte *blend_op));
+extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL)
+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
+ png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
+ png_byte blend_op));
+extern PNG_EXPORT(void,png_ensure_fcTL_is_valid)
+ PNGARG((png_structp png_ptr,
+ png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den,
+ png_byte dispose_op, png_byte blend_op));
+extern PNG_EXPORT(png_uint_32,png_get_next_frame_width)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_next_frame_height)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_next_frame_x_offset)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_next_frame_y_offset)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_num)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_den)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_byte,png_get_next_frame_dispose_op)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_byte,png_get_next_frame_blend_op)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_byte,png_get_first_frame_is_hidden)
+ PNGARG((png_structp png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32,png_set_first_frame_is_hidden)
+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
+#endif /* PNG_APNG_SUPPORTED */
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+extern PNG_EXPORT(void,png_read_frame_head) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* provide a list of chunks and how they are to be handled, if the built-in
+ handling or default unknown chunk handling is not desired. Any chunks not
+ listed will be handled in the default manner. The IHDR and IEND chunks
+ must not be listed.
+ keep = 0: follow default behaviour
+ = 1: do not keep
+ = 2: keep only if safe-to-copy
+ = 3: keep even if unsafe-to-copy
+*/
+extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
+ png_ptr, int keep, png_bytep chunk_list, int num_chunks));
+extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
+extern PNG_EXPORT(void, png_set_unknown_chunk_location)
+ PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
+extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
+ png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
+#endif
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
+ chunk_name));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ If you need to turn it off for a chunk that your application has freed,
+ you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
+extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int mask));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* The "params" pointer is currently not used and is for future expansion. */
+extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
+ png_infop info_ptr,
+ int transforms,
+ png_voidp params));
+extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
+ png_infop info_ptr,
+ int transforms,
+ png_voidp params));
+#endif
+
+/* Define PNG_DEBUG at compile time for debugging information. Higher
+ * numbers for PNG_DEBUG mean more debugging information. This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ */
+#ifdef PNG_DEBUG
+#if (PNG_DEBUG > 0)
+#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#include <crtdbg.h>
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m) _RPT0(_CRT_WARN,m)
+#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1)
+#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
+#endif
+#else /* PNG_DEBUG_FILE || !_MSC_VER */
+#ifndef PNG_DEBUG_FILE
+#define PNG_DEBUG_FILE stderr
+#endif /* PNG_DEBUG_FILE */
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m) \
+{ \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+}
+#define png_debug1(l,m,p1) \
+{ \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+}
+#define png_debug2(l,m,p1,p2) \
+{ \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+}
+#endif /* (PNG_DEBUG > 1) */
+#endif /* _MSC_VER */
+#endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+#define png_debug(l, m)
+#endif
+#ifndef png_debug1
+#define png_debug1(l, m, p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l, m, p1, p2)
+#endif
+
+extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+ png_ptr, png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT 0
+#define PNG_HANDLE_CHUNK_NEVER 1
+#define PNG_HANDLE_CHUNK_IF_SAFE 2
+#define PNG_HANDLE_CHUNK_ALWAYS 3
+
+/* Added to version 1.2.0 */
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#if defined(PNG_MMX_CODE_SUPPORTED)
+#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */
+#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */
+#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04
+#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08
+#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10
+#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20
+#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40
+#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
+#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */
+
+#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
+#define PNG_MMX_WRITE_FLAGS ( 0 )
+
+#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
+ | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \
+ | PNG_MMX_READ_FLAGS \
+ | PNG_MMX_WRITE_FLAGS )
+
+#define PNG_SELECT_READ 1
+#define PNG_SELECT_WRITE 2
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+#if !defined(PNG_1_0_X)
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
+ PNGARG((int flag_select, int *compilerID));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
+ PNGARG((int flag_select));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
+ PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
+ PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
+ PNGARG((png_structp png_ptr));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_asm_flags)
+ PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_mmx_thresholds)
+ PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
+ png_uint_32 mmx_rowbytes_threshold));
+
+#endif /* PNG_1_0_X */
+
+#if !defined(PNG_1_0_X)
+/* png.c, pnggccrd.c, or pngvcrd.c */
+extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler. */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
+ png_ptr, png_uint_32 strip_mode));
+#endif
+
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
+ png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
+extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
+ png_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
+ png_ptr));
+#endif
+
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines. However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems. There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same! 128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+
+# define png_composite(composite, fg, alpha, bg) \
+ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 - \
+ (png_uint_16)(alpha)) + (png_uint_16)128); \
+ (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(png_uint_32)(65535L - \
+ (png_uint_32)(alpha)) + (png_uint_32)32768L); \
+ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else /* standard method using integer division */
+
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ (png_uint_16)127) / 255)
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
+ (png_uint_32)32767) / (png_uint_32)65535L)
+
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+/* Inline macros to do direct reads of bytes from the input buffer. These
+ * require that you are using an architecture that uses PNG byte ordering
+ * (MSB first) and supports unaligned data storage. I think that PowerPC
+ * in big-endian mode and 680x0 are the only ones that will support this.
+ * The x86 line of processors definitely do not. The png_get_int_32()
+ * routine also assumes we are using two's complement format for negative
+ * values, which is almost certainly true.
+ */
+#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
+# define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+# define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+# define png_get_int_32(buf) ( *((png_int_32p) (buf)))
+#else
+extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
+extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
+extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
+#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
+extern PNG_EXPORT(png_uint_32,png_get_uint_31)
+ PNGARG((png_structp png_ptr, png_bytep buf));
+/* No png_get_int_16 -- may be added if there's a real need for it. */
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
+ */
+extern PNG_EXPORT(void,png_save_uint_32)
+ PNGARG((png_bytep buf, png_uint_32 i));
+extern PNG_EXPORT(void,png_save_int_32)
+ PNGARG((png_bytep buf, png_int_32 i));
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+extern PNG_EXPORT(void,png_save_uint_16)
+ PNGARG((png_bytep buf, unsigned int i));
+/* No png_save_int_16 -- may be added if there's a real need for it. */
+
+/* ************************************************************************* */
+
+/* These next functions are used internally in the code. They generally
+ * shouldn't be used unless you are writing code to add or replace some
+ * functionality in libpng. More information about most functions can
+ * be found in the files where the functions are located.
+ */
+
+
+/* Various modes of operation, that are visible to applications because
+ * they are used for unknown chunk location.
+ */
+#define PNG_HAVE_IHDR 0x01
+#define PNG_HAVE_PLTE 0x02
+#define PNG_HAVE_IDAT 0x04
+#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */
+#define PNG_HAVE_IEND 0x10
+
+#if defined(PNG_INTERNAL)
+
+/* More modes of operation. Note that after an init, mode is set to
+ * zero automatically when the structure is created.
+ */
+#define PNG_HAVE_gAMA 0x20
+#define PNG_HAVE_cHRM 0x40
+#define PNG_HAVE_sRGB 0x80
+#define PNG_HAVE_CHUNK_HEADER 0x100
+#define PNG_WROTE_tIME 0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY 0x800
+#define PNG_HAVE_PNG_SIGNATURE 0x1000
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+#define PNG_HAVE_acTL 0x4000
+#define PNG_HAVE_fcTL 0x8000L
+
+/* flags for the transformations the PNG library does on the image data */
+#define PNG_BGR 0x0001
+#define PNG_INTERLACE 0x0002
+#define PNG_PACK 0x0004
+#define PNG_SHIFT 0x0008
+#define PNG_SWAP_BYTES 0x0010
+#define PNG_INVERT_MONO 0x0020
+#define PNG_DITHER 0x0040
+#define PNG_BACKGROUND 0x0080
+#define PNG_BACKGROUND_EXPAND 0x0100
+ /* 0x0200 unused */
+#define PNG_16_TO_8 0x0400
+#define PNG_RGBA 0x0800
+#define PNG_EXPAND 0x1000
+#define PNG_GAMMA 0x2000
+#define PNG_GRAY_TO_RGB 0x4000
+#define PNG_FILLER 0x8000L
+#define PNG_PACKSWAP 0x10000L
+#define PNG_SWAP_ALPHA 0x20000L
+#define PNG_STRIP_ALPHA 0x40000L
+#define PNG_INVERT_ALPHA 0x80000L
+#define PNG_USER_TRANSFORM 0x100000L
+#define PNG_RGB_TO_GRAY_ERR 0x200000L
+#define PNG_RGB_TO_GRAY_WARN 0x400000L
+#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
+ /* 0x800000L Unused */
+#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
+ /* 0x4000000L unused */
+ /* 0x8000000L unused */
+ /* 0x10000000L unused */
+ /* 0x20000000L unused */
+ /* 0x40000000L unused */
+
+/* flags for png_create_struct */
+#define PNG_STRUCT_PNG 0x0001
+#define PNG_STRUCT_INFO 0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_SHIFT 3
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
+#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
+#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
+#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
+#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
+#define PNG_FLAG_ZLIB_FINISHED 0x0020
+#define PNG_FLAG_ROW_INIT 0x0040
+#define PNG_FLAG_FILLER_AFTER 0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
+#define PNG_FLAG_FREE_PLTE 0x1000
+#define PNG_FLAG_FREE_TRNS 0x2000
+#define PNG_FLAG_FREE_HIST 0x4000
+#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
+#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
+#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
+#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
+#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
+ /* 0x800000L unused */
+ /* 0x1000000L unused */
+ /* 0x2000000L unused */
+ /* 0x4000000L unused */
+ /* 0x8000000L unused */
+ /* 0x10000000L unused */
+ /* 0x20000000L unused */
+ /* 0x40000000L unused */
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+ PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
+ PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
+ PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+ abs((int)((c1).green) - (int)((c2).green)) + \
+ abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+ ((pixel_bits) >= 8 ? \
+ ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
+ (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+ ideal-delta..ideal+delta. Each argument is evaluated twice.
+ "ideal" and "delta" should be constants, normally simple
+ integers, "value" a variable. Added to libpng-1.2.6 JB */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+ ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* place to hold the signature string for a PNG file. */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+ PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8];
+#else
+#endif
+#endif /* PNG_NO_EXTERN */
+
+/* Constant strings for known chunk types. If you need to add a chunk,
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
+ */
+#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
+#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
+#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
+#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
+#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
+#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
+#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
+#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
+#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
+#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
+#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
+#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
+#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
+#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
+#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
+#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
+#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
+#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
+#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
+#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
+#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
+#define PNG_acTL png_byte png_acTL[5] = { 97, 99, 84, 76, '\0'}
+#define PNG_fcTL png_byte png_fcTL[5] = {102, 99, 84, 76, '\0'}
+#define PNG_fdAT png_byte png_fdAT[5] = {102, 100, 65, 84, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_acTL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_fcTL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_fdAT[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size));
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+ png_info_size));
+#endif
+
+extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+ png_info_size));
+
+/* Allocate memory for an internal libpng struct */
+PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
+
+/* Free memory from internal libpng struct */
+PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
+
+PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
+ malloc_fn, png_voidp mem_ptr));
+PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
+ png_free_ptr free_fn, png_voidp mem_ptr));
+
+/* Free any memory that info_ptr points to and reset struct. */
+PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
+
+/* Function to free memory for zlib */
+PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
+
+#ifdef PNG_SIZE_T
+/* Function to convert a sizeof an item to png_sizeof item */
+ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
+#endif
+
+/* Next four functions are used internally as callbacks. PNGAPI is required
+ * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */
+
+PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t length));
+#endif
+
+PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
+#endif
+#endif
+#else /* PNG_1_0_X */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t length));
+#endif
+#endif /* PNG_1_0_X */
+
+/* Reset the CRC variable */
+PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
+
+/* Write the "data" buffer to whatever output you are using. */
+PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length));
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length));
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
+ png_size_t length));
+
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
+ defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
+PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
+ int comp_type, png_charp chunkdata, png_size_t chunklength,
+ png_size_t prefix_length, png_size_t *data_length));
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
+
+/* Calculate the CRC over a section of data. Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
+ png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
+#endif
+
+/* simple function to write the signature */
+PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
+
+/* write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
+ png_uint_32 height,
+ int bit_depth, int color_type, int compression_method, int filter_method,
+ int interlace_method));
+
+PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
+ png_uint_32 num_pal));
+
+PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length));
+
+PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
+ file_gamma));
+#endif
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
+ int color_type));
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
+ double white_x, double white_y,
+ double red_x, double red_y, double green_x, double green_y,
+ double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
+ png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
+ int intent));
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+ png_charp name, int compression_type,
+ png_charp profile, int proflen));
+ /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
+ png_sPLT_tp palette));
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
+ png_color_16p values, int number, int color_type));
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
+ png_color_16p values, int color_type));
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
+ int num_hist));
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
+ png_charp key, png_charpp new_key));
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
+ png_charp text, png_size_t text_len));
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
+ png_charp text, png_size_t text_len, int compression));
+#endif
+
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
+ int compression, png_charp key, png_charp lang, png_charp lang_key,
+ png_charp text));
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */
+PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
+ png_int_32 x_offset, png_int_32 y_offset, int unit_type));
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
+ png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
+ png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+ int unit_type));
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
+ png_timep mod_time));
+#endif
+
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+ int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
+ int unit, png_charp width, png_charp height));
+#endif
+#endif
+#endif
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
+ png_uint_32 num_frames, png_uint_32 num_plays));
+
+PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
+ png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den,
+ png_byte dispose_op, png_byte blend_op));
+#endif
+
+/* Called when finished processing a row of data */
+PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
+
+/* Internal use only. Called before first row of data */
+PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
+#endif
+
+/* combine a row of data, dealing with alpha, etc. if requested */
+PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
+ int mask));
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+/* expand an interlaced row */
+/* OLD pre-1.0.9 interface:
+PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
+ png_bytep row, int pass, png_uint_32 transformations));
+ */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
+#endif
+
+/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* grab pixels out of a row for an interlaced pass */
+PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
+ png_bytep row, int pass));
+#endif
+
+/* unfilter a row */
+PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
+ png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
+
+/* Choose the best filter to use and filter the row data */
+PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
+ png_row_infop row_info));
+
+/* Write out the filtered row. */
+PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
+ png_bytep filtered_row));
+/* finish a row while reading, dealing with interlacing passes, etc. */
+PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
+
+/* initialize the row buffers, etc. */
+PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
+/* optional call to update the users info structure */
+PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+/* private, reset some things to become ready for reading next frame */
+PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr));
+#endif
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+/* private, reset some things to become ready for writing next frame */
+PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 width, png_uint_32 height));
+#endif
+
+/* these are the functions that do the transformations */
+#if defined(PNG_READ_FILLER_SUPPORTED)
+PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 filler, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
+ row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_8p sig_bits));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
+ png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
+
+# if defined(PNG_CORRECT_PALETTE_SUPPORTED)
+PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
+ png_colorp palette, int num_palette));
+# endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 bit_depth));
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_8p bit_depth));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background,
+ png_color_16p background_1,
+ png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+ png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+ png_uint_16pp gamma_16_to_1, int gamma_shift));
+#else
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background));
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
+ png_bytep gamma_table, png_uint_16pp gamma_16_table,
+ int gamma_shift));
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
+ png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
+PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
+ png_bytep row, png_color_16p trans_value));
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* decode the IHDR chunk */
+PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
+PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,
+ png_uint_32 length));
+#endif
+
+PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+
+PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
+ png_bytep chunk_name));
+
+/* handle the transformations for reading and writing */
+PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
+
+PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
+PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
+ png_bytep row));
+PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#if defined(PNG_MMX_CODE_SUPPORTED)
+/* png.c */ /* PRIVATE */
+PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr));
+#endif
+#endif
+
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_pHYs_SUPPORTED)
+PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
+#endif /* PNG_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* do not put anything past this line */
+#endif /* PNG_H */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngconf.h b/kernel/kls_png/ksquirrel-libs-png/pngconf.h
new file mode 100644
index 0000000..12a1848
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngconf.h
@@ -0,0 +1,1490 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.2.20 - September 8, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+#define PNG_1_2_X
+
+/*
+ * PNG_USER_CONFIG has to be defined on the compiler command line. This
+ * includes the resource compiler for Windows DLL configurations.
+ */
+#ifdef PNG_USER_CONFIG
+# ifndef PNG_USER_PRIVATEBUILD
+# define PNG_USER_PRIVATEBUILD
+# endif
+#include "pngusr.h"
+#endif
+
+/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */
+#ifdef PNG_CONFIGURE_LIBPNG
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#endif
+
+/*
+ * Added at libpng-1.2.8
+ *
+ * If you create a private DLL you need to define in "pngusr.h" the followings:
+ * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
+ * the DLL was built>
+ * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
+ * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
+ * distinguish your DLL from those of the official release. These
+ * correspond to the trailing letters that come after the version
+ * number and must match your private DLL name>
+ * e.g. // private DLL "libpng13gx.dll"
+ * #define PNG_USER_DLLFNAME_POSTFIX "gx"
+ *
+ * The following macros are also at your disposal if you want to complete the
+ * DLL VERSIONINFO structure.
+ * - PNG_USER_VERSIONINFO_COMMENTS
+ * - PNG_USER_VERSIONINFO_COMPANYNAME
+ * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
+ */
+
+#ifdef __STDC__
+#ifdef SPECIALBUILD
+# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
+ are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
+#endif
+
+#ifdef PRIVATEBUILD
+# pragma message("PRIVATEBUILD is deprecated.\
+ Use PNG_USER_PRIVATEBUILD instead.")
+# define PNG_USER_PRIVATEBUILD PRIVATEBUILD
+#endif
+#endif /* __STDC__ */
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* End of material added to libpng-1.2.8 */
+
+/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble
+# define PNG_WARN_UNINITIALIZED_ROW 1
+*/
+/* End of material added at libpng-1.2.19 */
+
+/* This is the size of the compression buffer, and thus the size of
+ * an IDAT chunk. Make this whatever size you feel is best for your
+ * machine. One of these will be allocated per png_struct. When this
+ * is full, it writes the data to the disk, and does some other
+ * calculations. Making this an extremely small size will slow
+ * the library down, but you may want to experiment to determine
+ * where it becomes significant, if you are concerned with memory
+ * usage. Note that zlib allocates at least 32Kb also. For readers,
+ * this describes the size of the buffer available to read the data in.
+ * Unless this gets smaller than the size of a row (compressed),
+ * it should not make much difference how big this is.
+ */
+
+#ifndef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 8192
+#endif
+
+/* Enable if you want a write-only libpng */
+
+#ifndef PNG_NO_READ_SUPPORTED
+# define PNG_READ_SUPPORTED
+#endif
+
+/* Enable if you want a read-only libpng */
+
+#ifndef PNG_NO_WRITE_SUPPORTED
+# define PNG_WRITE_SUPPORTED
+#endif
+
+/* Enabled by default in 1.2.0. You can disable this if you don't need to
+ support PNGs that are embedded in MNG datastreams */
+#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
+# ifndef PNG_MNG_FEATURES_SUPPORTED
+# define PNG_MNG_FEATURES_SUPPORTED
+# endif
+#endif
+
+#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
+# ifndef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FLOATING_POINT_SUPPORTED
+# endif
+#endif
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this. While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+#define PNG_MAX_MALLOC_64K
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+# define PNG_MAX_MALLOC_64K
+#endif
+
+/* Special munging to support doing things the 'cygwin' way:
+ * 'Normal' png-on-win32 defines/defaults:
+ * PNG_BUILD_DLL -- building dll
+ * PNG_USE_DLL -- building an application, linking to dll
+ * (no define) -- building static library, or building an
+ * application and linking to the static lib
+ * 'Cygwin' defines/defaults:
+ * PNG_BUILD_DLL -- (ignored) building the dll
+ * (no define) -- (ignored) building an application, linking to the dll
+ * PNG_STATIC -- (ignored) building the static lib, or building an
+ * application that links to the static lib.
+ * ALL_STATIC -- (ignored) building various static libs, or building an
+ * application that links to the static libs.
+ * Thus,
+ * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
+ * this bit of #ifdefs will define the 'correct' config variables based on
+ * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
+ * unnecessary.
+ *
+ * Also, the precedence order is:
+ * ALL_STATIC (since we can't #undef something outside our namespace)
+ * PNG_BUILD_DLL
+ * PNG_STATIC
+ * (nothing) == PNG_USE_DLL
+ *
+ * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
+ * of auto-import in binutils, we no longer need to worry about
+ * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore,
+ * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
+ * to __declspec() stuff. However, we DO need to worry about
+ * PNG_BUILD_DLL and PNG_STATIC because those change some defaults
+ * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
+ */
+#if defined(__CYGWIN__)
+# if defined(ALL_STATIC)
+# if defined(PNG_BUILD_DLL)
+# undef PNG_BUILD_DLL
+# endif
+# if defined(PNG_USE_DLL)
+# undef PNG_USE_DLL
+# endif
+# if defined(PNG_DLL)
+# undef PNG_DLL
+# endif
+# if !defined(PNG_STATIC)
+# define PNG_STATIC
+# endif
+# else
+# if defined (PNG_BUILD_DLL)
+# if defined(PNG_STATIC)
+# undef PNG_STATIC
+# endif
+# if defined(PNG_USE_DLL)
+# undef PNG_USE_DLL
+# endif
+# if !defined(PNG_DLL)
+# define PNG_DLL
+# endif
+# else
+# if defined(PNG_STATIC)
+# if defined(PNG_USE_DLL)
+# undef PNG_USE_DLL
+# endif
+# if defined(PNG_DLL)
+# undef PNG_DLL
+# endif
+# else
+# if !defined(PNG_USE_DLL)
+# define PNG_USE_DLL
+# endif
+# if !defined(PNG_DLL)
+# define PNG_DLL
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* This protects us against compilers that run on a windowing system
+ * and thus don't have or would rather us not use the stdio types:
+ * stdin, stdout, and stderr. The only one currently used is stderr
+ * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
+ * prevent these from being compiled and used. #defining PNG_NO_STDIO
+ * will also prevent these, plus will prevent the entire set of stdio
+ * macros and functions (FILE *, printf, etc.) from being compiled and used,
+ * unless (PNG_DEBUG > 0) has been #defined.
+ *
+ * #define PNG_NO_CONSOLE_IO
+ * #define PNG_NO_STDIO
+ */
+
+#if defined(_WIN32_WCE)
+# include <windows.h>
+ /* Console I/O functions are not supported on WindowsCE */
+# define PNG_NO_CONSOLE_IO
+# ifdef PNG_DEBUG
+# undef PNG_DEBUG
+# endif
+#endif
+
+#ifdef PNG_BUILD_DLL
+# ifndef PNG_CONSOLE_IO_SUPPORTED
+# ifndef PNG_NO_CONSOLE_IO
+# define PNG_NO_CONSOLE_IO
+# endif
+# endif
+#endif
+
+# ifdef PNG_NO_STDIO
+# ifndef PNG_NO_CONSOLE_IO
+# define PNG_NO_CONSOLE_IO
+# endif
+# ifdef PNG_DEBUG
+# if (PNG_DEBUG > 0)
+# include <stdio.h>
+# endif
+# endif
+# else
+# if !defined(_WIN32_WCE)
+/* "stdio.h" functions are not supported on WindowsCE */
+# include <stdio.h>
+# endif
+# endif
+
+/* This macro protects us against machines that don't have function
+ * prototypes (ie K&R style headers). If your compiler does not handle
+ * function prototypes, define this macro and use the included ansi2knr.
+ * I've always been able to use _NO_PROTO as the indicator, but you may
+ * need to drag the empty declaration out in front of here, or change the
+ * ifdef to suit your own needs.
+ */
+#ifndef PNGARG
+
+#ifdef OF /* zlib prototype munger */
+# define PNGARG(arglist) OF(arglist)
+#else
+
+#ifdef _NO_PROTO
+# define PNGARG(arglist) ()
+# ifndef PNG_TYPECAST_NULL
+# define PNG_TYPECAST_NULL
+# endif
+#else
+# define PNGARG(arglist) arglist
+#endif /* _NO_PROTO */
+
+
+#endif /* OF */
+
+#endif /* PNGARG */
+
+/* Try to determine if we are compiling on a Mac. Note that testing for
+ * just __MWERKS__ is not good enough, because the Codewarrior is now used
+ * on non-Mac platforms.
+ */
+#ifndef MACOS
+# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+# define MACOS
+# endif
+#endif
+
+/* enough people need this for various reasons to include it here */
+#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
+# include <sys/types.h>
+#endif
+
+#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
+# define PNG_SETJMP_SUPPORTED
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This is an attempt to force a single setjmp behaviour on Linux. If
+ * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
+ */
+
+# ifdef __linux__
+# ifdef _BSD_SOURCE
+# define PNG_SAVE_BSD_SOURCE
+# undef _BSD_SOURCE
+# endif
+# ifdef _SETJMP_H
+ /* If you encounter a compiler error here, see the explanation
+ * near the end of INSTALL.
+ */
+ __png.h__ already includes setjmp.h;
+ __dont__ include it again.;
+# endif
+# endif /* __linux__ */
+
+ /* include setjmp.h for error handling */
+# include <setjmp.h>
+
+# ifdef __linux__
+# ifdef PNG_SAVE_BSD_SOURCE
+# define _BSD_SOURCE
+# undef PNG_SAVE_BSD_SOURCE
+# endif
+# endif /* __linux__ */
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef BSD
+# include <strings.h>
+#else
+# include <string.h>
+#endif
+
+/* Other defines for things like memory and the like can go here. */
+#ifdef PNG_INTERNAL
+
+#include <stdlib.h>
+
+/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
+ * aren't usually used outside the library (as far as I know), so it is
+ * debatable if they should be exported at all. In the future, when it is
+ * possible to have run-time registry of chunk-handling functions, some of
+ * these will be made available again.
+#define PNG_EXTERN extern
+ */
+#define PNG_EXTERN
+
+/* Other defines specific to compilers can go here. Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+# if defined(MACOS)
+ /* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
+# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+# include <fp.h>
+# endif
+# else
+# include <math.h>
+# endif
+# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
+# include <m68881.h>
+# endif
+#endif
+
+/* Codewarrior on NT has linking problems without this. */
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
+# define PNG_ALWAYS_EXTERN
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+# include <mem.h>
+# include <alloc.h>
+#endif
+
+/* I have no idea why is this necessary... */
+#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
+ defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
+# include <malloc.h>
+#endif
+
+/* This controls how fine the dithering gets. As this allocates
+ * a largish chunk of memory (32K), those who are not as concerned
+ * with dithering quality can decrease some or all of these.
+ */
+#ifndef PNG_DITHER_RED_BITS
+# define PNG_DITHER_RED_BITS 5
+#endif
+#ifndef PNG_DITHER_GREEN_BITS
+# define PNG_DITHER_GREEN_BITS 5
+#endif
+#ifndef PNG_DITHER_BLUE_BITS
+# define PNG_DITHER_BLUE_BITS 5
+#endif
+
+/* This controls how fine the gamma correction becomes when you
+ * are only interested in 8 bits anyway. Increasing this value
+ * results in more memory being used, and more pow() functions
+ * being called to fill in the gamma tables. Don't set this value
+ * less then 8, and even that may not work (I haven't tested it).
+ */
+
+#ifndef PNG_MAX_GAMMA_8
+# define PNG_MAX_GAMMA_8 11
+#endif
+
+/* This controls how much a difference in gamma we can tolerate before
+ * we actually start doing gamma conversion.
+ */
+#ifndef PNG_GAMMA_THRESHOLD
+# define PNG_GAMMA_THRESHOLD 0.05
+#endif
+
+#endif /* PNG_INTERNAL */
+
+/* The following uses const char * instead of char * for error
+ * and warning message functions, so some compilers won't complain.
+ * If you do not want to use const, define PNG_NO_CONST here.
+ */
+
+#ifndef PNG_NO_CONST
+# define PNG_CONST const
+#else
+# define PNG_CONST
+#endif
+
+/* The following defines give you the ability to remove code from the
+ * library that you will not be using. I wish I could figure out how to
+ * automate this, but I can't do that without making it seriously hard
+ * on the users. So if you are not using an ability, change the #define
+ * to and #undef, and that part of the library will not be compiled. If
+ * your linker can't find a function, you may want to make sure the
+ * ability is defined here. Some of these depend upon some others being
+ * defined. I haven't figured out all the interactions here, so you may
+ * have to experiment awhile to get everything to compile. If you are
+ * creating or using a shared library, you probably shouldn't touch this,
+ * as it will affect the size of the structures, and this will cause bad
+ * things to happen if the library and/or application ever change.
+ */
+
+/* Any features you will not be using can be undef'ed here */
+
+/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
+ * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
+ * on the compile line, then pick and choose which ones to define without
+ * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
+ * if you only want to have a png-compliant reader/writer but don't need
+ * any of the extra transformations. This saves about 80 kbytes in a
+ * typical installation of the library. (PNG_NO_* form added in version
+ * 1.0.1c, for consistency)
+ */
+
+/* The size of the png_text structure changed in libpng-1.0.6 when
+ * iTXt support was added. iTXt support was turned off by default through
+ * libpng-1.2.x, to support old apps that malloc the png_text structure
+ * instead of calling png_set_text() and letting libpng malloc it. It
+ * was turned on by default in libpng-1.3.0.
+ */
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+# ifndef PNG_NO_iTXt_SUPPORTED
+# define PNG_NO_iTXt_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_iTXt
+# define PNG_NO_READ_iTXt
+# endif
+# ifndef PNG_NO_WRITE_iTXt
+# define PNG_NO_WRITE_iTXt
+# endif
+#endif
+
+#if !defined(PNG_NO_iTXt_SUPPORTED)
+# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
+# define PNG_READ_iTXt
+# endif
+# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
+# define PNG_WRITE_iTXt
+# endif
+#endif
+
+/* The following support, added after version 1.0.0, can be turned off here en
+ * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
+ * with old applications that require the length of png_struct and png_info
+ * to remain unchanged.
+ */
+
+#ifdef PNG_LEGACY_SUPPORTED
+# define PNG_NO_FREE_ME
+# define PNG_NO_READ_UNKNOWN_CHUNKS
+# define PNG_NO_WRITE_UNKNOWN_CHUNKS
+# define PNG_NO_READ_USER_CHUNKS
+# define PNG_NO_READ_iCCP
+# define PNG_NO_WRITE_iCCP
+# define PNG_NO_READ_iTXt
+# define PNG_NO_WRITE_iTXt
+# define PNG_NO_READ_sCAL
+# define PNG_NO_WRITE_sCAL
+# define PNG_NO_READ_sPLT
+# define PNG_NO_WRITE_sPLT
+# define PNG_NO_INFO_IMAGE
+# define PNG_NO_READ_RGB_TO_GRAY
+# define PNG_NO_READ_USER_TRANSFORM
+# define PNG_NO_WRITE_USER_TRANSFORM
+# define PNG_NO_USER_MEM
+# define PNG_NO_READ_EMPTY_PLTE
+# define PNG_NO_MNG_FEATURES
+# define PNG_NO_FIXED_POINT_SUPPORTED
+#endif
+
+/* Ignore attempt to turn off both floating and fixed point support */
+#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
+ !defined(PNG_NO_FIXED_POINT_SUPPORTED)
+# define PNG_FIXED_POINT_SUPPORTED
+#endif
+
+#ifndef PNG_NO_FREE_ME
+# define PNG_FREE_ME_SUPPORTED
+#endif
+
+#if defined(PNG_READ_SUPPORTED)
+
+#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_READ_TRANSFORMS)
+# define PNG_READ_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+# ifndef PNG_NO_READ_EXPAND
+# define PNG_READ_EXPAND_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SHIFT
+# define PNG_READ_SHIFT_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_PACK
+# define PNG_READ_PACK_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_BGR
+# define PNG_READ_BGR_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SWAP
+# define PNG_READ_SWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_PACKSWAP
+# define PNG_READ_PACKSWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_INVERT
+# define PNG_READ_INVERT_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_DITHER
+# define PNG_READ_DITHER_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_BACKGROUND
+# define PNG_READ_BACKGROUND_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_16_TO_8
+# define PNG_READ_16_TO_8_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_FILLER
+# define PNG_READ_FILLER_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_GAMMA
+# define PNG_READ_GAMMA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_GRAY_TO_RGB
+# define PNG_READ_GRAY_TO_RGB_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SWAP_ALPHA
+# define PNG_READ_SWAP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_INVERT_ALPHA
+# define PNG_READ_INVERT_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_STRIP_ALPHA
+# define PNG_READ_STRIP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_USER_TRANSFORM
+# define PNG_READ_USER_TRANSFORM_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_RGB_TO_GRAY
+# define PNG_READ_RGB_TO_GRAY_SUPPORTED
+# endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+#if !defined(PNG_NO_PROGRESSIVE_READ) && \
+ !defined(PNG_PROGRESSIVE_READ_SUPPORTED) /* if you don't do progressive */
+# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */
+#endif /* about interlacing capability! You'll */
+ /* still have interlacing unless you change the following line: */
+
+#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */
+
+#ifndef PNG_NO_READ_COMPOSITE_NODIV
+# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */
+# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */
+# endif
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated, will be removed from version 2.0.0.
+ Use PNG_MNG_FEATURES_SUPPORTED instead. */
+#ifndef PNG_NO_READ_EMPTY_PLTE
+# define PNG_READ_EMPTY_PLTE_SUPPORTED
+#endif
+#endif
+
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_WRITE_SUPPORTED)
+
+# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_WRITE_TRANSFORMS)
+# define PNG_WRITE_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+# ifndef PNG_NO_WRITE_SHIFT
+# define PNG_WRITE_SHIFT_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_PACK
+# define PNG_WRITE_PACK_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_BGR
+# define PNG_WRITE_BGR_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_SWAP
+# define PNG_WRITE_SWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_PACKSWAP
+# define PNG_WRITE_PACKSWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_INVERT
+# define PNG_WRITE_INVERT_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_FILLER
+# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */
+# endif
+# ifndef PNG_NO_WRITE_SWAP_ALPHA
+# define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_INVERT_ALPHA
+# define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_USER_TRANSFORM
+# define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+# endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \
+ !defined(PNG_WRITE_INTERLACING_SUPPORTED)
+#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
+ encoders, but can cause trouble
+ if left undefined */
+#endif
+
+#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
+ !defined(PNG_WRITE_WEIGHTED_FILTER) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_NO_WRITE_FLUSH
+# define PNG_WRITE_FLUSH_SUPPORTED
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+# define PNG_WRITE_EMPTY_PLTE_SUPPORTED
+#endif
+#endif
+
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef PNG_1_0_X
+# ifndef PNG_NO_ERROR_NUMBERS
+# define PNG_ERROR_NUMBERS_SUPPORTED
+# endif
+#endif /* PNG_1_0_X */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+# ifndef PNG_NO_USER_TRANSFORM_PTR
+# define PNG_USER_TRANSFORM_PTR_SUPPORTED
+# endif
+#endif
+
+#ifndef PNG_NO_STDIO
+# define PNG_TIME_RFC1123_SUPPORTED
+#endif
+
+/* This adds extra functions in pngget.c for accessing data from the
+ * info pointer (added in version 0.99)
+ * png_get_image_width()
+ * png_get_image_height()
+ * png_get_bit_depth()
+ * png_get_color_type()
+ * png_get_compression_type()
+ * png_get_filter_type()
+ * png_get_interlace_type()
+ * png_get_pixel_aspect_ratio()
+ * png_get_pixels_per_meter()
+ * png_get_x_offset_pixels()
+ * png_get_y_offset_pixels()
+ * png_get_x_offset_microns()
+ * png_get_y_offset_microns()
+ */
+#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
+# define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0
+ * and removed from version 1.2.20. The following will be removed
+ * from libpng-1.4.0
+*/
+
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE)
+# ifndef PNG_OPTIMIZED_CODE_SUPPORTED
+# define PNG_OPTIMIZED_CODE_SUPPORTED
+# endif
+#endif
+
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
+# ifndef PNG_ASSEMBLER_CODE_SUPPORTED
+# define PNG_ASSEMBLER_CODE_SUPPORTED
+# endif
+
+# if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4)
+ /* work around 64-bit gcc compiler bugs in gcc-3.x */
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_NO_MMX_CODE
+# endif
+# endif
+
+# if defined(__APPLE__)
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_NO_MMX_CODE
+# endif
+# endif
+
+# if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh))
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_NO_MMX_CODE
+# endif
+# endif
+
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_MMX_CODE_SUPPORTED
+# endif
+
+#endif
+/* end of obsolete code to be removed from libpng-1.4.0 */
+
+#if !defined(PNG_1_0_X)
+#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
+# define PNG_USER_MEM_SUPPORTED
+#endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.2.6 */
+#if !defined(PNG_1_0_X)
+#ifndef PNG_SET_USER_LIMITS_SUPPORTED
+#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED)
+# define PNG_SET_USER_LIMITS_SUPPORTED
+#endif
+#endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter
+ * how large, set these limits to 0x7fffffffL
+ */
+#ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000L
+#endif
+#ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000L
+#endif
+
+/* These are currently experimental features, define them if you want */
+
+/* very little testing */
+/*
+#ifdef PNG_READ_SUPPORTED
+# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+# endif
+#endif
+*/
+
+/* This is only for PowerPC big-endian and 680x0 systems */
+/* some testing */
+/*
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+# define PNG_READ_BIG_ENDIAN_SUPPORTED
+#endif
+*/
+
+/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
+/*
+#define PNG_NO_POINTER_INDEXING
+*/
+
+/* These functions are turned off by default, as they will be phased out. */
+/*
+#define PNG_USELESS_TESTS_SUPPORTED
+#define PNG_CORRECT_PALETTE_SUPPORTED
+*/
+
+/* Any chunks you are not interested in, you can undef here. The
+ * ones that allocate memory may be expecially important (hIST,
+ * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
+ * a bit smaller.
+ */
+
+#if defined(PNG_READ_SUPPORTED) && \
+ !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
+# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#if defined(PNG_WRITE_SUPPORTED) && \
+ !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
+# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_READ_TEXT
+# define PNG_NO_READ_iTXt
+# define PNG_NO_READ_tEXt
+# define PNG_NO_READ_zTXt
+#endif
+#ifndef PNG_NO_READ_bKGD
+# define PNG_READ_bKGD_SUPPORTED
+# define PNG_bKGD_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_cHRM
+# define PNG_READ_cHRM_SUPPORTED
+# define PNG_cHRM_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_gAMA
+# define PNG_READ_gAMA_SUPPORTED
+# define PNG_gAMA_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_hIST
+# define PNG_READ_hIST_SUPPORTED
+# define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+# define PNG_READ_iCCP_SUPPORTED
+# define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+# ifndef PNG_READ_iTXt_SUPPORTED
+# define PNG_READ_iTXt_SUPPORTED
+# endif
+# ifndef PNG_iTXt_SUPPORTED
+# define PNG_iTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_READ_oFFs
+# define PNG_READ_oFFs_SUPPORTED
+# define PNG_oFFs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pCAL
+# define PNG_READ_pCAL_SUPPORTED
+# define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+# define PNG_READ_sCAL_SUPPORTED
+# define PNG_sCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pHYs
+# define PNG_READ_pHYs_SUPPORTED
+# define PNG_pHYs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sBIT
+# define PNG_READ_sBIT_SUPPORTED
+# define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+# define PNG_READ_sPLT_SUPPORTED
+# define PNG_sPLT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sRGB
+# define PNG_READ_sRGB_SUPPORTED
+# define PNG_sRGB_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tEXt
+# define PNG_READ_tEXt_SUPPORTED
+# define PNG_tEXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tIME
+# define PNG_READ_tIME_SUPPORTED
+# define PNG_tIME_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tRNS
+# define PNG_READ_tRNS_SUPPORTED
+# define PNG_tRNS_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_zTXt
+# define PNG_READ_zTXt_SUPPORTED
+# define PNG_zTXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_APNG
+# define PNG_READ_APNG_SUPPORTED
+# define PNG_APNG_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
+# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_UNKNOWN_CHUNKS_SUPPORTED
+# endif
+# ifndef PNG_NO_HANDLE_AS_UNKNOWN
+# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# endif
+#endif
+#if !defined(PNG_NO_READ_USER_CHUNKS) && \
+ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+# define PNG_READ_USER_CHUNKS_SUPPORTED
+# define PNG_USER_CHUNKS_SUPPORTED
+# ifdef PNG_NO_READ_UNKNOWN_CHUNKS
+# undef PNG_NO_READ_UNKNOWN_CHUNKS
+# endif
+# ifdef PNG_NO_HANDLE_AS_UNKNOWN
+# undef PNG_NO_HANDLE_AS_UNKNOWN
+# endif
+#endif
+#ifndef PNG_NO_READ_OPT_PLTE
+# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
+#endif /* optional PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+ defined(PNG_READ_zTXt_SUPPORTED)
+# define PNG_READ_TEXT_SUPPORTED
+# define PNG_TEXT_SUPPORTED
+#endif
+
+#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
+
+#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_WRITE_TEXT
+# define PNG_NO_WRITE_iTXt
+# define PNG_NO_WRITE_tEXt
+# define PNG_NO_WRITE_zTXt
+#endif
+#ifndef PNG_NO_WRITE_bKGD
+# define PNG_WRITE_bKGD_SUPPORTED
+# ifndef PNG_bKGD_SUPPORTED
+# define PNG_bKGD_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_cHRM
+# define PNG_WRITE_cHRM_SUPPORTED
+# ifndef PNG_cHRM_SUPPORTED
+# define PNG_cHRM_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_gAMA
+# define PNG_WRITE_gAMA_SUPPORTED
+# ifndef PNG_gAMA_SUPPORTED
+# define PNG_gAMA_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_hIST
+# define PNG_WRITE_hIST_SUPPORTED
+# ifndef PNG_hIST_SUPPORTED
+# define PNG_hIST_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+# define PNG_WRITE_iCCP_SUPPORTED
+# ifndef PNG_iCCP_SUPPORTED
+# define PNG_iCCP_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+# ifndef PNG_WRITE_iTXt_SUPPORTED
+# define PNG_WRITE_iTXt_SUPPORTED
+# endif
+# ifndef PNG_iTXt_SUPPORTED
+# define PNG_iTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_oFFs
+# define PNG_WRITE_oFFs_SUPPORTED
+# ifndef PNG_oFFs_SUPPORTED
+# define PNG_oFFs_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_pCAL
+# define PNG_WRITE_pCAL_SUPPORTED
+# ifndef PNG_pCAL_SUPPORTED
+# define PNG_pCAL_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+# define PNG_WRITE_sCAL_SUPPORTED
+# ifndef PNG_sCAL_SUPPORTED
+# define PNG_sCAL_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_pHYs
+# define PNG_WRITE_pHYs_SUPPORTED
+# ifndef PNG_pHYs_SUPPORTED
+# define PNG_pHYs_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sBIT
+# define PNG_WRITE_sBIT_SUPPORTED
+# ifndef PNG_sBIT_SUPPORTED
+# define PNG_sBIT_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+# define PNG_WRITE_sPLT_SUPPORTED
+# ifndef PNG_sPLT_SUPPORTED
+# define PNG_sPLT_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sRGB
+# define PNG_WRITE_sRGB_SUPPORTED
+# ifndef PNG_sRGB_SUPPORTED
+# define PNG_sRGB_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tEXt
+# define PNG_WRITE_tEXt_SUPPORTED
+# ifndef PNG_tEXt_SUPPORTED
+# define PNG_tEXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tIME
+# define PNG_WRITE_tIME_SUPPORTED
+# ifndef PNG_tIME_SUPPORTED
+# define PNG_tIME_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tRNS
+# define PNG_WRITE_tRNS_SUPPORTED
+# ifndef PNG_tRNS_SUPPORTED
+# define PNG_tRNS_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_zTXt
+# define PNG_WRITE_zTXt_SUPPORTED
+# ifndef PNG_zTXt_SUPPORTED
+# define PNG_zTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_APNG
+# define PNG_WRITE_APNG_SUPPORTED
+# ifndef PNG_APNG_SUPPORTED
+# define PNG_APNG_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
+# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_UNKNOWN_CHUNKS_SUPPORTED
+# endif
+# ifndef PNG_NO_HANDLE_AS_UNKNOWN
+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# endif
+# endif
+#endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+ defined(PNG_WRITE_zTXt_SUPPORTED)
+# define PNG_WRITE_TEXT_SUPPORTED
+# ifndef PNG_TEXT_SUPPORTED
+# define PNG_TEXT_SUPPORTED
+# endif
+#endif
+
+#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
+
+/* Turn this off to disable png_read_png() and
+ * png_write_png() and leave the row_pointers member
+ * out of the info structure.
+ */
+#ifndef PNG_NO_INFO_IMAGE
+# define PNG_INFO_IMAGE_SUPPORTED
+#endif
+
+/* need the time information for reading tIME chunks */
+#if defined(PNG_tIME_SUPPORTED)
+# if !defined(_WIN32_WCE)
+ /* "time.h" functions are not supported on WindowsCE */
+# include <time.h>
+# endif
+#endif
+
+/* Some typedefs to get us started. These should be safe on most of the
+ * common platforms. The typedefs should be at least as large as the
+ * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
+ * don't have to be exactly that size. Some compilers dislike passing
+ * unsigned shorts as function parameters, so you may be better off using
+ * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
+ * want to have unsigned int for png_uint_32 instead of unsigned long.
+ */
+
+typedef unsigned long png_uint_32;
+typedef long png_int_32;
+typedef unsigned short png_uint_16;
+typedef short png_int_16;
+typedef unsigned char png_byte;
+
+/* This is usually size_t. It is typedef'ed just in case you need it to
+ change (I'm not sure if you will or not, so I thought I'd be safe) */
+#ifdef PNG_SIZE_T
+ typedef PNG_SIZE_T png_size_t;
+# define png_sizeof(x) png_convert_size(sizeof (x))
+#else
+ typedef size_t png_size_t;
+# define png_sizeof(x) sizeof (x)
+#endif
+
+/* The following is needed for medium model support. It cannot be in the
+ * PNG_INTERNAL section. Needs modification for other compilers besides
+ * MSC. Model independent support declares all arrays and pointers to be
+ * large using the far keyword. The zlib version used must also support
+ * model independent data. As of version zlib 1.0.4, the necessary changes
+ * have been made in zlib. The USE_FAR_KEYWORD define triggers other
+ * changes that are needed. (Tim Wegner)
+ */
+
+/* Separate compiler dependencies (problem here is that zlib.h always
+ defines FAR. (SJT) */
+#ifdef __BORLANDC__
+# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+# define LDATA 1
+# else
+# define LDATA 0
+# endif
+ /* GRR: why is Cygwin in here? Cygwin is not Borland C... */
+# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
+# define PNG_MAX_MALLOC_64K
+# if (LDATA != 1)
+# ifndef FAR
+# define FAR __far
+# endif
+# define USE_FAR_KEYWORD
+# endif /* LDATA != 1 */
+ /* Possibly useful for moving data out of default segment.
+ * Uncomment it if you want. Could also define FARDATA as
+ * const if your compiler supports it. (SJT)
+# define FARDATA FAR
+ */
+# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
+#endif /* __BORLANDC__ */
+
+
+/* Suggest testing for specific compiler first before testing for
+ * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
+ * making reliance oncertain keywords suspect. (SJT)
+ */
+
+/* MSC Medium model */
+#if defined(FAR)
+# if defined(M_I86MM)
+# define USE_FAR_KEYWORD
+# define FARDATA FAR
+# include <dos.h>
+# endif
+#endif
+
+/* SJT: default case */
+#ifndef FAR
+# define FAR
+#endif
+
+/* At this point FAR is always defined */
+#ifndef FARDATA
+# define FARDATA
+#endif
+
+/* Typedef for floating-point numbers that are converted
+ to fixed-point with a multiple of 100,000, e.g., int_gamma */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void FAR * png_voidp;
+typedef png_byte FAR * png_bytep;
+typedef png_uint_32 FAR * png_uint_32p;
+typedef png_int_32 FAR * png_int_32p;
+typedef png_uint_16 FAR * png_uint_16p;
+typedef png_int_16 FAR * png_int_16p;
+typedef PNG_CONST char FAR * png_const_charp;
+typedef char FAR * png_charp;
+typedef png_fixed_point FAR * png_fixed_point_p;
+
+#ifndef PNG_NO_STDIO
+#if defined(_WIN32_WCE)
+typedef HANDLE png_FILE_p;
+#else
+typedef FILE * png_FILE_p;
+#endif
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double FAR * png_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte FAR * FAR * png_bytepp;
+typedef png_uint_32 FAR * FAR * png_uint_32pp;
+typedef png_int_32 FAR * FAR * png_int_32pp;
+typedef png_uint_16 FAR * FAR * png_uint_16pp;
+typedef png_int_16 FAR * FAR * png_int_16pp;
+typedef PNG_CONST char FAR * FAR * png_const_charpp;
+typedef char FAR * FAR * png_charpp;
+typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double FAR * FAR * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char FAR * FAR * FAR * png_charppp;
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* SPC - Is this stuff deprecated? */
+/* It'll be removed as of libpng-1.3.0 - GR-P */
+/* libpng typedefs for types in zlib. If zlib changes
+ * or another compression library is used, then change these.
+ * Eliminates need to change all the source files.
+ */
+typedef charf * png_zcharp;
+typedef charf * FAR * png_zcharpp;
+typedef z_stream FAR * png_zstreamp;
+#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
+
+/*
+ * Define PNG_BUILD_DLL if the module being built is a Windows
+ * LIBPNG DLL.
+ *
+ * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
+ * It is equivalent to Microsoft predefined macro _DLL that is
+ * automatically defined when you compile using the share
+ * version of the CRT (C Run-Time library)
+ *
+ * The cygwin mods make this behavior a little different:
+ * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
+ * Define PNG_STATIC if you are building a static library for use with cygwin,
+ * -or- if you are building an application that you want to link to the
+ * static library.
+ * PNG_USE_DLL is defined by default (no user action needed) unless one of
+ * the other flags is defined.
+ */
+
+#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
+# define PNG_DLL
+#endif
+/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
+ * When building a static lib, default to no GLOBAL ARRAYS, but allow
+ * command-line override
+ */
+#if defined(__CYGWIN__)
+# if !defined(PNG_STATIC)
+# if defined(PNG_USE_GLOBAL_ARRAYS)
+# undef PNG_USE_GLOBAL_ARRAYS
+# endif
+# if !defined(PNG_USE_LOCAL_ARRAYS)
+# define PNG_USE_LOCAL_ARRAYS
+# endif
+# else
+# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
+# if defined(PNG_USE_GLOBAL_ARRAYS)
+# undef PNG_USE_GLOBAL_ARRAYS
+# endif
+# endif
+# endif
+# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+# define PNG_USE_LOCAL_ARRAYS
+# endif
+#endif
+
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+# if defined(PNG_NO_GLOBAL_ARRAYS) || \
+ (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER)
+# define PNG_USE_LOCAL_ARRAYS
+# else
+# define PNG_USE_GLOBAL_ARRAYS
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# undef PNGAPI
+# define PNGAPI __cdecl
+# undef PNG_IMPEXP
+# define PNG_IMPEXP
+#endif
+
+/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
+ * you may get warnings regarding the linkage of png_zalloc and png_zfree.
+ * Don't ignore those warnings; you must also reset the default calling
+ * convention in your compiler to match your PNGAPI, and you must build
+ * zlib and your applications the same way you build libpng.
+ */
+
+#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
+# ifndef PNG_NO_MODULEDEF
+# define PNG_NO_MODULEDEF
+# endif
+#endif
+
+#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
+# define PNG_IMPEXP
+#endif
+
+#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
+ (( defined(_Windows) || defined(_WINDOWS) || \
+ defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
+
+# ifndef PNGAPI
+# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
+# define PNGAPI __cdecl
+# else
+# define PNGAPI _cdecl
+# endif
+# endif
+
+# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
+ 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
+# define PNG_IMPEXP
+# endif
+
+# if !defined(PNG_IMPEXP)
+
+# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol
+# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol
+
+ /* Borland/Microsoft */
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
+# define PNG_EXPORT PNG_EXPORT_TYPE1
+# else
+# define PNG_EXPORT PNG_EXPORT_TYPE2
+# if defined(PNG_BUILD_DLL)
+# define PNG_IMPEXP __export
+# else
+# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
+ VC++ */
+# endif /* Exists in Borland C++ for
+ C++ classes (== huge) */
+# endif
+# endif
+
+# if !defined(PNG_IMPEXP)
+# if defined(PNG_BUILD_DLL)
+# define PNG_IMPEXP __declspec(dllexport)
+# else
+# define PNG_IMPEXP __declspec(dllimport)
+# endif
+# endif
+# endif /* PNG_IMPEXP */
+#else /* !(DLL || non-cygwin WINDOWS) */
+# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+# ifndef PNGAPI
+# define PNGAPI _System
+# endif
+# else
+# if 0 /* ... other platforms, with other meanings */
+# endif
+# endif
+#endif
+
+#ifndef PNGAPI
+# define PNGAPI
+#endif
+#ifndef PNG_IMPEXP
+# define PNG_IMPEXP
+#endif
+
+#ifdef PNG_BUILDSYMS
+# ifndef PNG_EXPORT
+# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
+# endif
+# ifdef PNG_USE_GLOBAL_ARRAYS
+# ifndef PNG_EXPORT_VAR
+# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
+# endif
+# endif
+#endif
+
+#ifndef PNG_EXPORT
+# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+# ifndef PNG_EXPORT_VAR
+# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
+# endif
+#endif
+
+/* User may want to use these so they are not in PNG_INTERNAL. Any library
+ * functions that are passed far data must be model independent.
+ */
+
+#ifndef PNG_ABORT
+# define PNG_ABORT() abort()
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#else
+# define png_jmpbuf(png_ptr) \
+ (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
+#endif
+
+#if defined(USE_FAR_KEYWORD) /* memory model independent fns */
+/* use this to make far-to-near assignments */
+# define CHECK 1
+# define NOCHECK 0
+# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+# define png_snprintf _fsnprintf /* Added to v 1.2.19 */
+# define png_strcpy _fstrcpy
+# define png_strncpy _fstrncpy /* Added to v 1.2.6 */
+# define png_strlen _fstrlen
+# define png_memcmp _fmemcmp /* SJT: added */
+# define png_memcpy _fmemcpy
+# define png_memset _fmemset
+#else /* use the usual functions */
+# define CVT_PTR(ptr) (ptr)
+# define CVT_PTR_NOCHECK(ptr) (ptr)
+# ifndef PNG_NO_SNPRINTF
+# ifdef _MSC_VER
+# define png_snprintf _snprintf /* Added to v 1.2.19 */
+# define png_snprintf2 _snprintf
+# define png_snprintf6 _snprintf
+# else
+# define png_snprintf snprintf /* Added to v 1.2.19 */
+# define png_snprintf2 snprintf
+# define png_snprintf6 snprintf
+# endif
+# else
+ /* You don't have or don't want to use snprintf(). Caution: Using
+ * sprintf instead of snprintf exposes your application to accidental
+ * or malevolent buffer overflows. If you don't have snprintf()
+ * as a general rule you should provide one (you can get one from
+ * Portable OpenSSH). */
+# define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
+# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
+# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
+ sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
+# endif
+# define png_strcpy strcpy
+# define png_strncpy strncpy /* Added to v 1.2.6 */
+# define png_strlen strlen
+# define png_memcmp memcmp /* SJT: added */
+# define png_memcpy memcpy
+# define png_memset memset
+#endif
+/* End of memory model independent support */
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+# undef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 65536L
+#endif
+
+/* Added at libpng-1.2.8 */
+#endif /* PNG_VERSION_INFO_ONLY */
+
+#endif /* PNGCONF_H */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngerror.c b/kernel/kls_png/ksquirrel-libs-png/pngerror.c
new file mode 100644
index 0000000..159c5d4
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngerror.c
@@ -0,0 +1,341 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * Last changed in libpng 1.2.20 September 8, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all error handling. Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions. See the instructions
+ * at each function.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+static void /* PRIVATE */
+png_default_error PNGARG((png_structp png_ptr,
+ png_const_charp error_message));
+#ifndef PNG_NO_WARNINGS
+static void /* PRIVATE */
+png_default_warning PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+#endif /* PNG_NO_WARNINGS */
+
+/* This function is called whenever there is a fatal error. This function
+ * should not be changed. If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+#ifndef PNG_NO_ERROR_TEXT
+void PNGAPI
+png_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ char msg[16];
+ if (png_ptr != NULL)
+ {
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+ {
+ if (*error_message == '#')
+ {
+ int offset;
+ for (offset=1; offset<15; offset++)
+ if (*(error_message+offset) == ' ')
+ break;
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ int i;
+ for (i=0; i<offset-1; i++)
+ msg[i]=error_message[i+1];
+ msg[i]='\0';
+ error_message=msg;
+ }
+ else
+ error_message+=offset;
+ }
+ else
+ {
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ msg[0]='0';
+ msg[1]='\0';
+ error_message=msg;
+ }
+ }
+ }
+ }
+#endif
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_ptr, error_message);
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, error_message);
+}
+#else
+void PNGAPI
+png_err(png_structp png_ptr)
+{
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_ptr, '\0');
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, '\0');
+}
+#endif /* PNG_NO_ERROR_TEXT */
+
+#ifndef PNG_NO_WARNINGS
+/* This function is called whenever there is a non-fatal error. This function
+ * should not be changed. If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+ int offset = 0;
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+ {
+ if (*warning_message == '#')
+ {
+ for (offset=1; offset<15; offset++)
+ if (*(warning_message+offset) == ' ')
+ break;
+ }
+ }
+ if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+ (*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
+ }
+ else
+ png_default_warning(png_ptr, warning_message+offset);
+}
+#endif /* PNG_NO_WARNINGS */
+
+
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk. The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message. The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+#if !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT)
+static void /* PRIVATE */
+png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
+ error_message)
+{
+ int iout = 0, iin = 0;
+
+ while (iin < 4)
+ {
+ int c = png_ptr->chunk_name[iin++];
+ if (isnonalpha(c))
+ {
+ buffer[iout++] = '[';
+ buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+ buffer[iout++] = png_digit[c & 0x0f];
+ buffer[iout++] = ']';
+ }
+ else
+ {
+ buffer[iout++] = (png_byte)c;
+ }
+ }
+
+ if (error_message == NULL)
+ buffer[iout] = 0;
+ else
+ {
+ buffer[iout++] = ':';
+ buffer[iout++] = ' ';
+ png_strncpy(buffer+iout, error_message, 63);
+ buffer[iout+63] = 0;
+ }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_chunk_error(png_structp png_ptr, png_const_charp error_message)
+{
+ char msg[18+64];
+ if (png_ptr == NULL)
+ png_error(png_ptr, error_message);
+ else
+ {
+ png_format_buffer(png_ptr, msg, error_message);
+ png_error(png_ptr, msg);
+ }
+}
+#endif /* PNG_READ_SUPPORTED */
+#endif /* !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) */
+
+#ifndef PNG_NO_WARNINGS
+void PNGAPI
+png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+ char msg[18+64];
+ if (png_ptr == NULL)
+ png_warning(png_ptr, warning_message);
+ else
+ {
+ png_format_buffer(png_ptr, msg, warning_message);
+ png_warning(png_ptr, msg);
+ }
+}
+#endif /* PNG_NO_WARNINGS */
+
+
+/* This is the default error handling function. Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void /* PRIVATE */
+png_default_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*error_message == '#')
+ {
+ int offset;
+ char error_number[16];
+ for (offset=0; offset<15; offset++)
+ {
+ error_number[offset] = *(error_message+offset+1);
+ if (*(error_message+offset) == ' ')
+ break;
+ }
+ if((offset > 1) && (offset < 15))
+ {
+ error_number[offset-1]='\0';
+ fprintf(stderr, "libpng error no. %s: %s\n", error_number,
+ error_message+offset);
+ }
+ else
+ fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
+ }
+ else
+#endif
+ fprintf(stderr, "libpng error: %s\n", error_message);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ if (png_ptr)
+ {
+# ifdef USE_FAR_KEYWORD
+ {
+ jmp_buf jmpbuf;
+ png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+ longjmp(jmpbuf, 1);
+ }
+# else
+ longjmp(png_ptr->jmpbuf, 1);
+# endif
+ }
+#else
+ PNG_ABORT();
+#endif
+#ifdef PNG_NO_CONSOLE_IO
+ error_message = error_message; /* make compiler happy */
+#endif
+}
+
+#ifndef PNG_NO_WARNINGS
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want them to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+#ifndef PNG_NO_CONSOLE_IO
+# ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*warning_message == '#')
+ {
+ int offset;
+ char warning_number[16];
+ for (offset=0; offset<15; offset++)
+ {
+ warning_number[offset]=*(warning_message+offset+1);
+ if (*(warning_message+offset) == ' ')
+ break;
+ }
+ if((offset > 1) && (offset < 15))
+ {
+ warning_number[offset-1]='\0';
+ fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
+ warning_message+offset);
+ }
+ else
+ fprintf(stderr, "libpng warning: %s\n", warning_message);
+ }
+ else
+# endif
+ fprintf(stderr, "libpng warning: %s\n", warning_message);
+#else
+ warning_message = warning_message; /* make compiler happy */
+#endif
+ png_ptr = png_ptr; /* make compiler happy */
+}
+#endif /* PNG_NO_WARNINGS */
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings. Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur. The return
+ * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->error_ptr = error_ptr;
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return NULL;
+ return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
+{
+ if(png_ptr != NULL)
+ {
+ png_ptr->flags &=
+ ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+ }
+}
+#endif
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pnggccrd.c b/kernel/kls_png/ksquirrel-libs-png/pnggccrd.c
new file mode 100644
index 0000000..a7248d6
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pnggccrd.c
@@ -0,0 +1,101 @@
+/* pnggccrd.c was removed from libpng-1.2.20. */
+
+/* This code snippet is for use by configure's compilation test. */
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
+ defined(PNG_MMX_CODE_SUPPORTED)
+int PNGAPI png_dummy_mmx_support(void);
+
+static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
+
+int PNGAPI
+png_dummy_mmx_support(void) __attribute__((noinline));
+
+int PNGAPI
+png_dummy_mmx_support(void)
+{
+ int result;
+#if defined(PNG_MMX_CODE_SUPPORTED) // superfluous, but what the heck
+ __asm__ __volatile__ (
+#if defined(__x86_64__)
+ "pushq %%rbx \n\t" // rbx gets clobbered by CPUID instruction
+ "pushq %%rcx \n\t" // so does rcx...
+ "pushq %%rdx \n\t" // ...and rdx (but rcx & rdx safe on Linux)
+ "pushfq \n\t" // save Eflag to stack
+ "popq %%rax \n\t" // get Eflag from stack into rax
+ "movq %%rax, %%rcx \n\t" // make another copy of Eflag in rcx
+ "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+ "pushq %%rax \n\t" // save modified Eflag back to stack
+ "popfq \n\t" // restore modified value to Eflag reg
+ "pushfq \n\t" // save Eflag to stack
+ "popq %%rax \n\t" // get Eflag from stack
+ "pushq %%rcx \n\t" // save original Eflag to stack
+ "popfq \n\t" // restore original Eflag
+#else
+ "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction
+ "pushl %%ecx \n\t" // so does ecx...
+ "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux)
+ "pushfl \n\t" // save Eflag to stack
+ "popl %%eax \n\t" // get Eflag from stack into eax
+ "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx
+ "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+ "pushl %%eax \n\t" // save modified Eflag back to stack
+ "popfl \n\t" // restore modified value to Eflag reg
+ "pushfl \n\t" // save Eflag to stack
+ "popl %%eax \n\t" // get Eflag from stack
+ "pushl %%ecx \n\t" // save original Eflag to stack
+ "popfl \n\t" // restore original Eflag
+#endif
+ "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag
+ "jz 0f \n\t" // if same, CPUID instr. is not supported
+
+ "xorl %%eax, %%eax \n\t" // set eax to zero
+// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode)
+ "cpuid \n\t" // get the CPU identification info
+ "cmpl $1, %%eax \n\t" // make sure eax return non-zero value
+ "jl 0f \n\t" // if eax is zero, MMX is not supported
+
+ "xorl %%eax, %%eax \n\t" // set eax to zero and...
+ "incl %%eax \n\t" // ...increment eax to 1. This pair is
+ // faster than the instruction "mov eax, 1"
+ "cpuid \n\t" // get the CPU identification info again
+ "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
+ "cmpl $0, %%edx \n\t" // 0 = MMX not supported
+ "jz 0f \n\t" // non-zero = yes, MMX IS supported
+
+ "movl $1, %%eax \n\t" // set return value to 1
+ "jmp 1f \n\t" // DONE: have MMX support
+
+ "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions
+ "movl $0, %%eax \n\t" // set return value to 0
+ "1: \n\t" // .RETURN: target label for jump instructions
+#if defined(__x86_64__)
+ "popq %%rdx \n\t" // restore rdx
+ "popq %%rcx \n\t" // restore rcx
+ "popq %%rbx \n\t" // restore rbx
+#else
+ "popl %%edx \n\t" // restore edx
+ "popl %%ecx \n\t" // restore ecx
+ "popl %%ebx \n\t" // restore ebx
+#endif
+
+// "ret \n\t" // DONE: no MMX support
+ // (fall through to standard C "ret")
+
+ : "=a" (result) // output list
+
+ : // any variables used on input (none)
+
+ // no clobber list
+// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually
+// , "memory" // if write to a variable gcc thought was in a reg
+// , "cc" // "condition codes" (flag bits)
+ );
+ _mmx_supported = result;
+#else
+ _mmx_supported = 0;
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+ return _mmx_supported;
+}
+#endif
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngget.c b/kernel/kls_png/ksquirrel-libs-png/pngget.c
new file mode 100644
index 0000000..d700f30
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngget.c
@@ -0,0 +1,1062 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * Last changed in libpng 1.2.15 January 5, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+png_uint_32 PNGAPI
+png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->valid & flag);
+ else
+ return(0);
+}
+
+png_uint_32 PNGAPI
+png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->rowbytes);
+ else
+ return(0);
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+png_bytepp PNGAPI
+png_get_rows(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->row_pointers);
+ else
+ return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->width;
+ }
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->height;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->bit_depth;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->color_type;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->filter_type;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->interlace_type;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->compression_type;
+ }
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
+ if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+ return (0);
+ else return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
+ if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+ return (0);
+ else return (info_ptr->y_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
+ if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
+ info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
+ return (0);
+ else return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+ {
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
+ if (info_ptr->x_pixels_per_unit == 0)
+ return ((float)0.0);
+ else
+ return ((float)((float)info_ptr->y_pixels_per_unit
+ /(float)info_ptr->x_pixels_per_unit));
+ }
+#else
+ return (0.0);
+#endif
+ return ((float)0.0);
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+ return (0);
+ else return (info_ptr->x_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+ return (0);
+ else return (info_ptr->y_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+ return (0);
+ else return (info_ptr->x_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+ return (0);
+ else return (info_ptr->y_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+float PNGAPI
+png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
+ *.00003937);
+}
+
+float PNGAPI
+png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
+ *.00003937);
+}
+
+#if defined(PNG_pHYs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function\n", "pHYs");
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ if(*unit_type == 1)
+ {
+ if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+ if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+ }
+ }
+ }
+ return (retval);
+}
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+png_byte PNGAPI
+png_get_channels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->channels);
+ else
+ return (0);
+}
+
+png_bytep PNGAPI
+png_get_signature(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->signature);
+ else
+ return (NULL);
+}
+
+#if defined(PNG_bKGD_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+ png_color_16p *background)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+ && background != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "bKGD");
+ *background = &(info_ptr->background);
+ return (PNG_INFO_bKGD);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+ double *white_x, double *white_y, double *red_x, double *red_y,
+ double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ {
+ png_debug1(1, "in %s retrieval function\n", "cHRM");
+ if (white_x != NULL)
+ *white_x = (double)info_ptr->x_white;
+ if (white_y != NULL)
+ *white_y = (double)info_ptr->y_white;
+ if (red_x != NULL)
+ *red_x = (double)info_ptr->x_red;
+ if (red_y != NULL)
+ *red_y = (double)info_ptr->y_red;
+ if (green_x != NULL)
+ *green_x = (double)info_ptr->x_green;
+ if (green_y != NULL)
+ *green_y = (double)info_ptr->y_green;
+ if (blue_x != NULL)
+ *blue_x = (double)info_ptr->x_blue;
+ if (blue_y != NULL)
+ *blue_y = (double)info_ptr->y_blue;
+ return (PNG_INFO_cHRM);
+ }
+ return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+ png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+ png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ {
+ png_debug1(1, "in %s retrieval function\n", "cHRM");
+ if (white_x != NULL)
+ *white_x = info_ptr->int_x_white;
+ if (white_y != NULL)
+ *white_y = info_ptr->int_y_white;
+ if (red_x != NULL)
+ *red_x = info_ptr->int_x_red;
+ if (red_y != NULL)
+ *red_y = info_ptr->int_y_red;
+ if (green_x != NULL)
+ *green_x = info_ptr->int_x_green;
+ if (green_y != NULL)
+ *green_y = info_ptr->int_y_green;
+ if (blue_x != NULL)
+ *blue_x = info_ptr->int_x_blue;
+ if (blue_y != NULL)
+ *blue_y = info_ptr->int_y_blue;
+ return (PNG_INFO_cHRM);
+ }
+ return (0);
+}
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+ && file_gamma != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "gAMA");
+ *file_gamma = (double)info_ptr->gamma;
+ return (PNG_INFO_gAMA);
+ }
+ return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point *int_file_gamma)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+ && int_file_gamma != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "gAMA");
+ *int_file_gamma = info_ptr->int_gamma;
+ return (PNG_INFO_gAMA);
+ }
+ return (0);
+}
+#endif
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+ && file_srgb_intent != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "sRGB");
+ *file_srgb_intent = (int)info_ptr->srgb_intent;
+ return (PNG_INFO_sRGB);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+ png_charpp name, int *compression_type,
+ png_charpp profile, png_uint_32 *proflen)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+ && name != NULL && profile != NULL && proflen != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "iCCP");
+ *name = info_ptr->iccp_name;
+ *profile = info_ptr->iccp_profile;
+ /* compression_type is a dummy so the API won't have to change
+ if we introduce multiple compression types later. */
+ *proflen = (int)info_ptr->iccp_proflen;
+ *compression_type = (int)info_ptr->iccp_compression;
+ return (PNG_INFO_iCCP);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+ png_sPLT_tpp spalettes)
+{
+ if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+ {
+ *spalettes = info_ptr->splt_palettes;
+ return ((png_uint_32)info_ptr->splt_palettes_num);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+ && hist != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "hIST");
+ *hist = info_ptr->hist;
+ return (PNG_INFO_hIST);
+ }
+ return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+ int *color_type, int *interlace_type, int *compression_type,
+ int *filter_type)
+
+{
+ if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
+ bit_depth != NULL && color_type != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "IHDR");
+ *width = info_ptr->width;
+ *height = info_ptr->height;
+ *bit_depth = info_ptr->bit_depth;
+ if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
+ png_error(png_ptr, "Invalid bit depth");
+ *color_type = info_ptr->color_type;
+ if (info_ptr->color_type > 6)
+ png_error(png_ptr, "Invalid color type");
+ if (compression_type != NULL)
+ *compression_type = info_ptr->compression_type;
+ if (filter_type != NULL)
+ *filter_type = info_ptr->filter_type;
+ if (interlace_type != NULL)
+ *interlace_type = info_ptr->interlace_type;
+
+ /* check for potential overflow of rowbytes */
+ if (*width == 0 || *width > PNG_UINT_31_MAX)
+ png_error(png_ptr, "Invalid image width");
+ if (*height == 0 || *height > PNG_UINT_31_MAX)
+ png_error(png_ptr, "Invalid image height");
+ if (info_ptr->width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 64 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ {
+ png_warning(png_ptr,
+ "Width too large for libpng to process image data.");
+ }
+ return (1);
+ }
+ return (0);
+}
+
+#if defined(PNG_oFFs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+ png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+ && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "oFFs");
+ *offset_x = info_ptr->x_offset;
+ *offset_y = info_ptr->y_offset;
+ *unit_type = (int)info_ptr->offset_unit_type;
+ return (PNG_INFO_oFFs);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+ png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+ png_charp *units, png_charpp *params)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+ && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+ nparams != NULL && units != NULL && params != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "pCAL");
+ *purpose = info_ptr->pcal_purpose;
+ *X0 = info_ptr->pcal_X0;
+ *X1 = info_ptr->pcal_X1;
+ *type = (int)info_ptr->pcal_type;
+ *nparams = (int)info_ptr->pcal_nparams;
+ *units = info_ptr->pcal_units;
+ *params = info_ptr->pcal_params;
+ return (PNG_INFO_pCAL);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+ int *unit, double *width, double *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_pixel_width;
+ *height = info_ptr->scal_pixel_height;
+ return (PNG_INFO_sCAL);
+ }
+ return(0);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+ int *unit, png_charpp width, png_charpp height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_s_width;
+ *height = info_ptr->scal_s_height;
+ return (PNG_INFO_sCAL);
+ }
+ return(0);
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function\n", "pHYs");
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ }
+ }
+ return (retval);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+ int *num_palette)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+ && palette != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "PLTE");
+ *palette = info_ptr->palette;
+ *num_palette = info_ptr->num_palette;
+ png_debug1(3, "num_palette = %d\n", *num_palette);
+ return (PNG_INFO_PLTE);
+ }
+ return (0);
+}
+
+#if defined(PNG_sBIT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+ && sig_bit != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "sBIT");
+ *sig_bit = &(info_ptr->sig_bit);
+ return (PNG_INFO_sBIT);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
+ int *num_text)
+{
+ if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+ {
+ png_debug1(1, "in %s retrieval function\n",
+ (png_ptr->chunk_name[0] == '\0' ? "text"
+ : (png_const_charp)png_ptr->chunk_name));
+ if (text_ptr != NULL)
+ *text_ptr = info_ptr->text;
+ if (num_text != NULL)
+ *num_text = info_ptr->num_text;
+ return ((png_uint_32)info_ptr->num_text);
+ }
+ if (num_text != NULL)
+ *num_text = 0;
+ return(0);
+}
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+ && mod_time != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "tIME");
+ *mod_time = &(info_ptr->mod_time);
+ return (PNG_INFO_tIME);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+ png_bytep *trans, int *num_trans, png_color_16p *trans_values)
+{
+ png_uint_32 retval = 0;
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_debug1(1, "in %s retrieval function\n", "tRNS");
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (trans != NULL)
+ {
+ *trans = info_ptr->trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ if (trans_values != NULL)
+ *trans_values = &(info_ptr->trans_values);
+ }
+ else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+ {
+ if (trans_values != NULL)
+ {
+ *trans_values = &(info_ptr->trans_values);
+ retval |= PNG_INFO_tRNS;
+ }
+ if(trans != NULL)
+ *trans = NULL;
+ }
+ if(num_trans != NULL)
+ {
+ *num_trans = info_ptr->num_trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ }
+ return (retval);
+}
+#endif
+
+#if defined(PNG_APNG_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_acTL(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *num_frames, png_uint_32 *num_plays)
+{
+ png_debug1(1, "in %s retrieval function\n", "acTL");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_acTL) &&
+ num_frames != NULL && num_plays != NULL)
+ {
+ *num_frames = info_ptr->num_frames;
+ *num_plays = info_ptr->num_plays;
+ return (1);
+ }
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_num_frames()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->num_frames);
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_num_plays()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->num_plays);
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *width, png_uint_32 *height,
+ png_uint_32 *x_offset, png_uint_32 *y_offset,
+ png_uint_16 *delay_num, png_uint_16 *delay_den,
+ png_byte *dispose_op, png_byte *blend_op)
+{
+ png_debug1(1, "in %s retrieval function\n", "fcTL");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_fcTL) &&
+ width != NULL && height != NULL &&
+ x_offset != NULL && x_offset != NULL &&
+ delay_num != NULL && delay_den != NULL &&
+ dispose_op != NULL && blend_op != NULL)
+ {
+ *width = info_ptr->next_frame_width;
+ *height = info_ptr->next_frame_height;
+ *x_offset = info_ptr->next_frame_x_offset;
+ *y_offset = info_ptr->next_frame_y_offset;
+ *delay_num = info_ptr->next_frame_delay_num;
+ *delay_den = info_ptr->next_frame_delay_den;
+ *dispose_op = info_ptr->next_frame_dispose_op;
+ *blend_op = info_ptr->next_frame_blend_op;
+ return (1);
+ }
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_width()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_width);
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_height()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_height);
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_x_offset()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_x_offset);
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_y_offset()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_y_offset);
+ return (0);
+}
+
+png_uint_16 PNGAPI
+png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_delay_num()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_delay_num);
+ return (0);
+}
+
+png_uint_16 PNGAPI
+png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_delay_den()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_delay_den);
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_dispose_op()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_dispose_op);
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_get_next_frame_blend_op()\n");
+
+ if (png_ptr != NULL && info_ptr != NULL)
+ return (info_ptr->next_frame_blend_op);
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_first_frame_is_hidden()\n");
+
+ if (png_ptr != NULL)
+ return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
+
+ return 0;
+}
+#endif /* PNG_APNG_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+ png_unknown_chunkpp unknowns)
+{
+ if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+ {
+ *unknowns = info_ptr->unknown_chunks;
+ return ((png_uint_32)info_ptr->unknown_chunks_num);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_structp png_ptr)
+{
+ return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+png_uint_32 PNGAPI
+png_get_compression_buffer_size(png_structp png_ptr)
+{
+ return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
+}
+#endif
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifndef PNG_1_0_X
+/* this function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flags (png_structp png_ptr)
+{
+ /* obsolete, to be removed from libpng-1.4.0 */
+ return (png_ptr? 0L: 0L);
+}
+
+/* this function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flagmask (int flag_select)
+{
+ /* obsolete, to be removed from libpng-1.4.0 */
+ flag_select=flag_select;
+ return 0L;
+}
+
+ /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
+/* this function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_flagmask (int flag_select, int *compilerID)
+{
+ /* obsolete, to be removed from libpng-1.4.0 */
+ flag_select=flag_select;
+ *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
+ return 0L;
+}
+
+/* this function was added to libpng 1.2.0 */
+png_byte PNGAPI
+png_get_mmx_bitdepth_threshold (png_structp png_ptr)
+{
+ /* obsolete, to be removed from libpng-1.4.0 */
+ return (png_ptr? 0: 0);
+}
+
+/* this function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_rowbytes_threshold (png_structp png_ptr)
+{
+ /* obsolete, to be removed from libpng-1.4.0 */
+ return (png_ptr? 0L: 0L);
+}
+#endif /* ?PNG_1_0_X */
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* these functions were added to libpng 1.2.6 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_width_max : 0);
+}
+png_uint_32 PNGAPI
+png_get_user_height_max (png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_height_max : 0);
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pnghack.h b/kernel/kls_png/ksquirrel-libs-png/pnghack.h
new file mode 100644
index 0000000..cba90da
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pnghack.h
@@ -0,0 +1,409 @@
+#ifndef PNG_NAMES_HACK
+#define PNG_NAMES_HACK
+
+#define png_access_version_number my_png_access_version_number
+#define png_acTL my_png_acTL
+#define png_bKGD my_png_bKGD
+#define png_build_gamma_table my_png_build_gamma_table
+#define png_build_grayscale_palette my_png_build_grayscale_palette
+#define png_calculate_crc my_png_calculate_crc
+#define png_check_chunk_name my_png_check_chunk_name
+#define png_check_keyword my_png_check_keyword
+#define png_check_sig my_png_check_sig
+#define png_cHRM my_png_cHRM
+#define png_chunk_error my_png_chunk_error
+#define png_chunk_warning my_png_chunk_warning
+#define png_combine_row my_png_combine_row
+#define png_convert_from_struct_tm my_png_convert_from_struct_tm
+#define png_convert_from_time_t my_png_convert_from_time_t
+#define png_convert_to_rfc1123 my_png_convert_to_rfc1123
+#define png_crc_error my_png_crc_error
+#define png_crc_finish my_png_crc_finish
+#define png_crc_read my_png_crc_read
+#define png_create_info_struct my_png_create_info_struct
+#define png_create_read_struct my_png_create_read_struct
+#define png_create_read_struct_2 my_png_create_read_struct_2
+#define png_create_struct my_png_create_struct
+#define png_create_struct_2 my_png_create_struct_2
+#define png_create_write_struct my_png_create_write_struct
+#define png_create_write_struct_2 my_png_create_write_struct_2
+#define png_data_freer my_png_data_freer
+#define png_decompress_chunk my_png_decompress_chunk
+#define png_default_flush my_png_default_flush
+#define png_default_read_data my_png_default_read_data
+#define png_default_write_data my_png_default_write_data
+#define png_destroy_info_struct my_png_destroy_info_struct
+#define png_destroy_read_struct my_png_destroy_read_struct
+#define png_destroy_struct my_png_destroy_struct
+#define png_destroy_struct_2 my_png_destroy_struct_2
+#define png_destroy_write_struct my_png_destroy_write_struct
+#define png_digit my_png_digit
+#define png_do_background my_png_do_background
+#define png_do_bgr my_png_do_bgr
+#define png_do_chop my_png_do_chop
+#define png_do_dither my_png_do_dither
+#define png_do_expand my_png_do_expand
+#define png_do_expand_palette my_png_do_expand_palette
+#define png_do_gamma my_png_do_gamma
+#define png_do_gray_to_rgb my_png_do_gray_to_rgb
+#define png_do_invert my_png_do_invert
+#define png_do_pack my_png_do_pack
+#define png_do_packswap my_png_do_packswap
+#define png_do_read_filler my_png_do_read_filler
+#define png_do_read_interlace my_png_do_read_interlace
+#define png_do_read_intrapixel my_png_do_read_intrapixel
+#define png_do_read_invert_alpha my_png_do_read_invert_alpha
+#define png_do_read_swap_alpha my_png_do_read_swap_alpha
+#define png_do_read_transformations my_png_do_read_transformations
+#define png_do_rgb_to_gray my_png_do_rgb_to_gray
+#define png_do_shift my_png_do_shift
+#define png_do_strip_filler my_png_do_strip_filler
+#define png_do_swap my_png_do_swap
+#define png_do_unpack my_png_do_unpack
+#define png_do_unshift my_png_do_unshift
+#define png_do_write_interlace my_png_do_write_interlace
+#define png_do_write_intrapixel my_png_do_write_intrapixel
+#define png_do_write_invert_alpha my_png_do_write_invert_alpha
+#define png_do_write_swap_alpha my_png_do_write_swap_alpha
+#define png_do_write_transformations my_png_do_write_transformations
+#define png_ensure_fcTL_is_valid my_png_ensure_fcTL_is_valid
+#define png_ensure_sequence_number my_png_ensure_sequence_number
+#define png_error my_png_error
+#define png_fcTL my_png_fcTL
+#define png_fdAT my_png_fdAT
+#define png_flush my_png_flush
+#define png_format_buffer my_png_format_buffer
+#define png_free my_png_free
+#define png_free_data my_png_free_data
+#define png_free_default my_png_free_default
+#define png_gAMA my_png_gAMA
+#define png_gamma_shift my_png_gamma_shift
+#define png_get_acTL my_png_get_acTL
+#define png_get_asm_flagmask my_png_get_asm_flagmask
+#define png_get_asm_flags my_png_get_asm_flags
+#define png_get_bit_depth my_png_get_bit_depth
+#define png_get_bKGD my_png_get_bKGD
+#define png_get_channels my_png_get_channels
+#define png_get_cHRM my_png_get_cHRM
+#define png_get_cHRM_fixed my_png_get_cHRM_fixed
+#define png_get_color_type my_png_get_color_type
+#define png_get_compression_buffer_size my_png_get_compression_buffer_size
+#define png_get_compression_type my_png_get_compression_type
+#define png_get_copyright my_png_get_copyright
+#define png_get_error_ptr my_png_get_error_ptr
+#define png_get_filter_type my_png_get_filter_type
+#define png_get_first_frame_is_hidden my_png_get_first_frame_is_hidden
+#define png_get_gAMA my_png_get_gAMA
+#define png_get_gAMA_fixed my_png_get_gAMA_fixed
+#define png_get_header_ver my_png_get_header_ver
+#define png_get_header_version my_png_get_header_version
+#define png_get_hIST my_png_get_hIST
+#define png_get_iCCP my_png_get_iCCP
+#define png_get_IHDR my_png_get_IHDR
+#define png_get_image_height my_png_get_image_height
+#define png_get_image_width my_png_get_image_width
+#define png_get_int_32 my_png_get_int_32
+#define png_get_interlace_type my_png_get_interlace_type
+#define png_get_io_ptr my_png_get_io_ptr
+#define png_get_libpng_ver my_png_get_libpng_ver
+#define png_get_mem_ptr my_png_get_mem_ptr
+#define png_get_mmx_bitdepth_threshold my_png_get_mmx_bitdepth_threshold
+#define png_get_mmx_flagmask my_png_get_mmx_flagmask
+#define png_get_mmx_rowbytes_threshold my_png_get_mmx_rowbytes_threshold
+#define png_get_next_frame_blend_op my_png_get_next_frame_blend_op
+#define png_get_next_frame_delay_den my_png_get_next_frame_delay_den
+#define png_get_next_frame_delay_num my_png_get_next_frame_delay_num
+#define png_get_next_frame_dispose_op my_png_get_next_frame_dispose_op
+#define png_get_next_frame_fcTL my_png_get_next_frame_fcTL
+#define png_get_next_frame_height my_png_get_next_frame_height
+#define png_get_next_frame_width my_png_get_next_frame_width
+#define png_get_next_frame_x_offset my_png_get_next_frame_x_offset
+#define png_get_next_frame_y_offset my_png_get_next_frame_y_offset
+#define png_get_num_frames my_png_get_num_frames
+#define png_get_num_plays my_png_get_num_plays
+#define png_get_oFFs my_png_get_oFFs
+#define png_get_pCAL my_png_get_pCAL
+#define png_get_pHYs my_png_get_pHYs
+#define png_get_pixel_aspect_ratio my_png_get_pixel_aspect_ratio
+#define png_get_pixels_per_meter my_png_get_pixels_per_meter
+#define png_get_PLTE my_png_get_PLTE
+#define png_get_progressive_ptr my_png_get_progressive_ptr
+#define png_get_rgb_to_gray_status my_png_get_rgb_to_gray_status
+#define png_get_rowbytes my_png_get_rowbytes
+#define png_get_rows my_png_get_rows
+#define png_get_sBIT my_png_get_sBIT
+#define png_get_sCAL my_png_get_sCAL
+#define png_get_signature my_png_get_signature
+#define png_get_sPLT my_png_get_sPLT
+#define png_get_sRGB my_png_get_sRGB
+#define png_get_text my_png_get_text
+#define png_get_tIME my_png_get_tIME
+#define png_get_tRNS my_png_get_tRNS
+#define png_get_uint_16 my_png_get_uint_16
+#define png_get_uint_31 my_png_get_uint_31
+#define png_get_uint_32 my_png_get_uint_32
+#define png_get_unknown_chunks my_png_get_unknown_chunks
+#define png_get_user_chunk_ptr my_png_get_user_chunk_ptr
+#define png_get_user_height_max my_png_get_user_height_max
+#define png_get_user_transform_ptr my_png_get_user_transform_ptr
+#define png_get_user_width_max my_png_get_user_width_max
+#define png_get_valid my_png_get_valid
+#define png_get_x_offset_microns my_png_get_x_offset_microns
+#define png_get_x_offset_pixels my_png_get_x_offset_pixels
+#define png_get_x_pixels_per_meter my_png_get_x_pixels_per_meter
+#define png_get_y_offset_microns my_png_get_y_offset_microns
+#define png_get_y_offset_pixels my_png_get_y_offset_pixels
+#define png_get_y_pixels_per_meter my_png_get_y_pixels_per_meter
+#define png_handle_acTL my_png_handle_acTL
+#define png_handle_as_unknown my_png_handle_as_unknown
+#define png_handle_bKGD my_png_handle_bKGD
+#define png_handle_cHRM my_png_handle_cHRM
+#define png_handle_fcTL my_png_handle_fcTL
+#define png_handle_fdAT my_png_handle_fdAT
+#define png_handle_gAMA my_png_handle_gAMA
+#define png_handle_hIST my_png_handle_hIST
+#define png_handle_iCCP my_png_handle_iCCP
+#define png_handle_IEND my_png_handle_IEND
+#define png_handle_IHDR my_png_handle_IHDR
+#define png_handle_oFFs my_png_handle_oFFs
+#define png_handle_pCAL my_png_handle_pCAL
+#define png_handle_pHYs my_png_handle_pHYs
+#define png_handle_PLTE my_png_handle_PLTE
+#define png_handle_sBIT my_png_handle_sBIT
+#define png_handle_sCAL my_png_handle_sCAL
+#define png_handle_sPLT my_png_handle_sPLT
+#define png_handle_sRGB my_png_handle_sRGB
+#define png_handle_tEXt my_png_handle_tEXt
+#define png_handle_tIME my_png_handle_tIME
+#define png_handle_tRNS my_png_handle_tRNS
+#define png_handle_unknown my_png_handle_unknown
+#define png_handle_zTXt my_png_handle_zTXt
+#define png_have_info my_png_have_info
+#define png_hIST my_png_hIST
+#define png_iCCP my_png_iCCP
+#define png_IDAT my_png_IDAT
+#define png_IEND my_png_IEND
+#define png_IHDR my_png_IHDR
+#define png_info_destroy my_png_info_destroy
+#define png_info_init my_png_info_init
+#define png_info_init_3 my_png_info_init_3
+#define png_init_io my_png_init_io
+#define png_init_read_transformations my_png_init_read_transformations
+#define png_iTXt my_png_iTXt
+#define png_libpng_ver my_png_libpng_ver
+#define png_malloc my_png_malloc
+#define png_malloc_default my_png_malloc_default
+#define png_malloc_warn my_png_malloc_warn
+#define png_memcpy_check my_png_memcpy_check
+#define png_memset_check my_png_memset_check
+#define png_mmx_support my_png_mmx_support
+#define png_oFFs my_png_oFFs
+#define png_pass_dsp_mask my_png_pass_dsp_mask
+#define png_pass_inc my_png_pass_inc
+#define png_pass_mask my_png_pass_mask
+#define png_pass_start my_png_pass_start
+#define png_pass_yinc my_png_pass_yinc
+#define png_pass_ystart my_png_pass_ystart
+#define png_pCAL my_png_pCAL
+#define png_permit_empty_plte my_png_permit_empty_plte
+#define png_permit_mng_features my_png_permit_mng_features
+#define png_pHYs my_png_pHYs
+#define png_PLTE my_png_PLTE
+#define png_process_data my_png_process_data
+#define png_process_IDAT_data my_png_process_IDAT_data
+#define png_process_some_data my_png_process_some_data
+#define png_progressive_combine_row my_png_progressive_combine_row
+#define png_progressive_read_reset my_png_progressive_read_reset
+#define png_push_crc_finish my_png_push_crc_finish
+#define png_push_crc_skip my_png_push_crc_skip
+#define png_push_fill_buffer my_png_push_fill_buffer
+#define png_push_handle_tEXt my_png_push_handle_tEXt
+#define png_push_handle_unknown my_png_push_handle_unknown
+#define png_push_handle_zTXt my_png_push_handle_zTXt
+#define png_push_have_end my_png_push_have_end
+#define png_push_have_info my_png_push_have_info
+#define png_push_have_row my_png_push_have_row
+#define png_push_process_row my_png_push_process_row
+#define png_push_read_chunk my_png_push_read_chunk
+#define png_push_read_IDAT my_png_push_read_IDAT
+#define png_push_read_sig my_png_push_read_sig
+#define png_push_read_tEXt my_png_push_read_tEXt
+#define png_push_read_zTXt my_png_push_read_zTXt
+#define png_push_restore_buffer my_png_push_restore_buffer
+#define png_push_save_buffer my_png_push_save_buffer
+#define png_read_data my_png_read_data
+#define png_read_destroy my_png_read_destroy
+#define png_read_end my_png_read_end
+#define png_read_filter_row my_png_read_filter_row
+#define png_read_finish_row my_png_read_finish_row
+#define png_read_frame_head my_png_read_frame_head
+#define png_read_image my_png_read_image
+#define png_read_info my_png_read_info
+#define png_read_init my_png_read_init
+#define png_read_init_2 my_png_read_init_2
+#define png_read_init_3 my_png_read_init_3
+#define png_read_png my_png_read_png
+#define png_read_push_finish_row my_png_read_push_finish_row
+#define png_read_reinit my_png_read_reinit
+#define png_read_reset my_png_read_reset
+#define png_read_row my_png_read_row
+#define png_read_rows my_png_read_rows
+#define png_read_start_row my_png_read_start_row
+#define png_read_transform_info my_png_read_transform_info
+#define png_read_update_info my_png_read_update_info
+#define png_reset_crc my_png_reset_crc
+#define png_reset_zstream my_png_reset_zstream
+#define png_save_int_32 my_png_save_int_32
+#define png_save_uint_16 my_png_save_uint_16
+#define png_save_uint_32 my_png_save_uint_32
+#define png_sBIT my_png_sBIT
+#define png_sCAL my_png_sCAL
+#define png_set_acTL my_png_set_acTL
+#define png_set_add_alpha my_png_set_add_alpha
+#define png_set_asm_flags my_png_set_asm_flags
+#define png_set_background my_png_set_background
+#define png_set_bgr my_png_set_bgr
+#define png_set_bKGD my_png_set_bKGD
+#define png_set_cHRM my_png_set_cHRM
+#define png_set_cHRM_fixed my_png_set_cHRM_fixed
+#define png_set_compression_buffer_size my_png_set_compression_buffer_size
+#define png_set_compression_level my_png_set_compression_level
+#define png_set_compression_mem_level my_png_set_compression_mem_level
+#define png_set_compression_method my_png_set_compression_method
+#define png_set_compression_strategy my_png_set_compression_strategy
+#define png_set_compression_window_bits my_png_set_compression_window_bits
+#define png_set_crc_action my_png_set_crc_action
+#define png_set_dither my_png_set_dither
+#define png_set_error_fn my_png_set_error_fn
+#define png_set_expand my_png_set_expand
+#define png_set_expand_gray_1_2_4_to_8 my_png_set_expand_gray_1_2_4_to_8
+#define png_set_filler my_png_set_filler
+#define png_set_filter my_png_set_filter
+#define png_set_filter_heuristics my_png_set_filter_heuristics
+#define png_set_first_frame_is_hidden my_png_set_first_frame_is_hidden
+#define png_set_flush my_png_set_flush
+#define png_set_gAMA my_png_set_gAMA
+#define png_set_gAMA_fixed my_png_set_gAMA_fixed
+#define png_set_gamma my_png_set_gamma
+#define png_set_gray_1_2_4_to_8 my_png_set_gray_1_2_4_to_8
+#define png_set_gray_to_rgb my_png_set_gray_to_rgb
+#define png_set_hIST my_png_set_hIST
+#define png_set_iCCP my_png_set_iCCP
+#define png_set_IHDR my_png_set_IHDR
+#define png_set_interlace_handling my_png_set_interlace_handling
+#define png_set_invalid my_png_set_invalid
+#define png_set_invert_alpha my_png_set_invert_alpha
+#define png_set_invert_mono my_png_set_invert_mono
+#define png_set_keep_unknown_chunks my_png_set_keep_unknown_chunks
+#define png_set_mem_fn my_png_set_mem_fn
+#define png_set_mmx_thresholds my_png_set_mmx_thresholds
+#define png_set_next_frame_fcTL my_png_set_next_frame_fcTL
+#define png_set_oFFs my_png_set_oFFs
+#define png_set_packing my_png_set_packing
+#define png_set_packswap my_png_set_packswap
+#define png_set_palette_to_rgb my_png_set_palette_to_rgb
+#define png_set_pCAL my_png_set_pCAL
+#define png_set_pHYs my_png_set_pHYs
+#define png_set_PLTE my_png_set_PLTE
+#define png_set_progressive_frame_fn my_png_set_progressive_frame_fn
+#define png_set_progressive_read_fn my_png_set_progressive_read_fn
+#define png_set_read_fn my_png_set_read_fn
+#define png_set_read_status_fn my_png_set_read_status_fn
+#define png_set_read_user_chunk_fn my_png_set_read_user_chunk_fn
+#define png_set_read_user_transform_fn my_png_set_read_user_transform_fn
+#define png_set_rgb_to_gray my_png_set_rgb_to_gray
+#define png_set_rgb_to_gray_fixed my_png_set_rgb_to_gray_fixed
+#define png_set_rows my_png_set_rows
+#define png_set_sBIT my_png_set_sBIT
+#define png_set_sCAL my_png_set_sCAL
+#define png_set_shift my_png_set_shift
+#define png_set_sig_bytes my_png_set_sig_bytes
+#define png_set_sPLT my_png_set_sPLT
+#define png_set_sRGB my_png_set_sRGB
+#define png_set_sRGB_gAMA_and_cHRM my_png_set_sRGB_gAMA_and_cHRM
+#define png_set_strip_16 my_png_set_strip_16
+#define png_set_strip_alpha my_png_set_strip_alpha
+#define png_set_strip_error_numbers my_png_set_strip_error_numbers
+#define png_set_swap my_png_set_swap
+#define png_set_swap_alpha my_png_set_swap_alpha
+#define png_set_text my_png_set_text
+#define png_set_text_2 my_png_set_text_2
+#define png_set_tIME my_png_set_tIME
+#define png_set_tRNS my_png_set_tRNS
+#define png_set_tRNS_to_alpha my_png_set_tRNS_to_alpha
+#define png_set_unknown_chunk_location my_png_set_unknown_chunk_location
+#define png_set_unknown_chunks my_png_set_unknown_chunks
+#define png_set_user_limits my_png_set_user_limits
+#define png_set_user_transform_info my_png_set_user_transform_info
+#define png_set_write_fn my_png_set_write_fn
+#define png_set_write_status_fn my_png_set_write_status_fn
+#define png_set_write_user_transform_fn my_png_set_write_user_transform_fn
+#define png_sig my_png_sig
+#define png_sig_cmp my_png_sig_cmp
+#define png_sPLT my_png_sPLT
+#define png_sRGB my_png_sRGB
+#define png_start_read_image my_png_start_read_image
+#define png_tEXt my_png_tEXt
+#define png_text_compress my_png_text_compress
+#define png_tIME my_png_tIME
+#define png_tRNS my_png_tRNS
+#define png_warning my_png_warning
+#define png_write_acTL my_png_write_acTL
+#define png_write_bKGD my_png_write_bKGD
+#define png_write_cHRM my_png_write_cHRM
+#define png_write_cHRM_fixed my_png_write_cHRM_fixed
+#define png_write_chunk my_png_write_chunk
+#define png_write_chunk_data my_png_write_chunk_data
+#define png_write_chunk_end my_png_write_chunk_end
+#define png_write_chunk_start my_png_write_chunk_start
+#define png_write_compressed_data_out my_png_write_compressed_data_out
+#define png_write_data my_png_write_data
+#define png_write_destroy my_png_write_destroy
+#define png_write_end my_png_write_end
+#define png_write_fcTL my_png_write_fcTL
+#define png_write_filtered_row my_png_write_filtered_row
+#define png_write_find_filter my_png_write_find_filter
+#define png_write_finish_row my_png_write_finish_row
+#define png_write_flush my_png_write_flush
+#define png_write_frame_head my_png_write_frame_head
+#define png_write_frame_tail my_png_write_frame_tail
+#define png_write_gAMA my_png_write_gAMA
+#define png_write_gAMA_fixed my_png_write_gAMA_fixed
+#define png_write_hIST my_png_write_hIST
+#define png_write_iCCP my_png_write_iCCP
+#define png_write_IDAT my_png_write_IDAT
+#define png_write_IEND my_png_write_IEND
+#define png_write_IHDR my_png_write_IHDR
+#define png_write_image my_png_write_image
+#define png_write_info my_png_write_info
+#define png_write_info_before_PLTE my_png_write_info_before_PLTE
+#define png_write_init my_png_write_init
+#define png_write_init_2 my_png_write_init_2
+#define png_write_init_3 my_png_write_init_3
+#define png_write_oFFs my_png_write_oFFs
+#define png_write_pCAL my_png_write_pCAL
+#define png_write_pHYs my_png_write_pHYs
+#define png_write_PLTE my_png_write_PLTE
+#define png_write_png my_png_write_png
+#define png_write_reinit my_png_write_reinit
+#define png_write_reset my_png_write_reset
+#define png_write_row my_png_write_row
+#define png_write_rows my_png_write_rows
+#define png_write_sBIT my_png_write_sBIT
+#define png_write_sCAL my_png_write_sCAL
+#define png_write_sig my_png_write_sig
+#define png_write_sPLT my_png_write_sPLT
+#define png_write_sRGB my_png_write_sRGB
+#define png_write_start_row my_png_write_start_row
+#define png_write_tEXt my_png_write_tEXt
+#define png_write_tIME my_png_write_tIME
+#define png_write_tRNS my_png_write_tRNS
+#define png_write_zTXt my_png_write_zTXt
+#define png_zalloc my_png_zalloc
+#define png_zfree my_png_zfree
+#define png_zTXt my_png_zTXt
+#define short_months my_short_months
+#define twobppswaptable my_twobppswaptable
+#define onebppswaptable my_onebppswaptable
+
+#endif
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngmem.c b/kernel/kls_png/ksquirrel-libs-png/pngmem.c
new file mode 100644
index 0000000..248060f
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngmem.c
@@ -0,0 +1,608 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * Last changed in libpng 1.2.13 November 13, 2006
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2006 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all memory allocation. Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* if you change this, be sure to change the one in png.h also */
+
+/* Allocate memory for a png_struct. The malloc and memset can be replaced
+ by a single call to calloc() if this is thought to improve performance. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Alternate version of png_create_struct, for use with user-defined malloc. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_size_t size;
+ png_voidp struct_ptr;
+
+ if (type == PNG_STRUCT_INFO)
+ size = png_sizeof(png_info);
+ else if (type == PNG_STRUCT_PNG)
+ size = png_sizeof(png_struct);
+ else
+ return (png_get_copyright(NULL));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(malloc_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
+ }
+ else
+#endif /* PNG_USER_MEM_SUPPORTED */
+ struct_ptr = (png_voidp)farmalloc(size);
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+ return (struct_ptr);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+ png_voidp mem_ptr)
+{
+#endif
+ if (struct_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(free_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ (*(free_fn))(png_ptr, struct_ptr);
+ return;
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+ farfree (struct_ptr);
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more then 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * Borland seems to have a problem in DOS mode for exactly 64K.
+ * It gives you a segment with an offset of 8 (perhaps to store its
+ * memory stuff). zlib doesn't like this at all, so we have to
+ * detect and deal with it. This code should not be needed in
+ * Windows or OS/2 modes, and only in 16 bit mode. This code has
+ * been updated by Alexander Lehmann for version 0.89 to waste less
+ * memory.
+ *
+ * Note that we can't use png_size_t for the "size" declaration,
+ * since on some systems a png_size_t is a 16-bit quantity, and as a
+ * result, we would be truncating potentially larger memory requests
+ * (which should cause a fatal error) and introducing major problems.
+ */
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(png_ptr->malloc_fn != NULL)
+ ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+ else
+ ret = (png_malloc_default(png_ptr, size));
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of memory!");
+ return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (size > (png_uint_32)65536L)
+ {
+ png_warning(png_ptr, "Cannot Allocate > 64K");
+ ret = NULL;
+ }
+ else
+#endif
+
+ if (size != (size_t)size)
+ ret = NULL;
+ else if (size == (png_uint_32)65536L)
+ {
+ if (png_ptr->offset_table == NULL)
+ {
+ /* try to see if we need to do any of this fancy stuff */
+ ret = farmalloc(size);
+ if (ret == NULL || ((png_size_t)ret & 0xffff))
+ {
+ int num_blocks;
+ png_uint_32 total_size;
+ png_bytep table;
+ int i;
+ png_byte huge * hptr;
+
+ if (ret != NULL)
+ {
+ farfree(ret);
+ ret = NULL;
+ }
+
+ if(png_ptr->zlib_window_bits > 14)
+ num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+ else
+ num_blocks = 1;
+ if (png_ptr->zlib_mem_level >= 7)
+ num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
+ else
+ num_blocks++;
+
+ total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
+
+ table = farmalloc(total_size);
+
+ if (table == NULL)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
+ else
+ png_warning(png_ptr, "Out Of Memory.");
+#endif
+ return (NULL);
+ }
+
+ if ((png_size_t)table & 0xfff0)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr,
+ "Farmalloc didn't return normalized pointer");
+ else
+ png_warning(png_ptr,
+ "Farmalloc didn't return normalized pointer");
+#endif
+ return (NULL);
+ }
+
+ png_ptr->offset_table = table;
+ png_ptr->offset_table_ptr = farmalloc(num_blocks *
+ png_sizeof (png_bytep));
+
+ if (png_ptr->offset_table_ptr == NULL)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
+ else
+ png_warning(png_ptr, "Out Of memory.");
+#endif
+ return (NULL);
+ }
+
+ hptr = (png_byte huge *)table;
+ if ((png_size_t)hptr & 0xf)
+ {
+ hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
+ hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
+ }
+ for (i = 0; i < num_blocks; i++)
+ {
+ png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
+ hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
+ }
+
+ png_ptr->offset_table_number = num_blocks;
+ png_ptr->offset_table_count = 0;
+ png_ptr->offset_table_count_free = 0;
+ }
+ }
+
+ if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
+ else
+ png_warning(png_ptr, "Out of Memory.");
+#endif
+ return (NULL);
+ }
+
+ ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
+ }
+ else
+ ret = farmalloc(size);
+
+#ifndef PNG_USER_MEM_SUPPORTED
+ if (ret == NULL)
+ {
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
+ else
+ png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
+ }
+#endif
+
+ return (ret);
+}
+
+/* free a pointer allocated by png_malloc(). In the default
+ configuration, png_ptr is not used, but is passed in case it
+ is needed. If ptr is NULL, return without taking any action. */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ {
+ (*(png_ptr->free_fn))(png_ptr, ptr);
+ return;
+ }
+ else png_free_default(png_ptr, ptr);
+}
+
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if(png_ptr == NULL) return;
+
+ if (png_ptr->offset_table != NULL)
+ {
+ int i;
+
+ for (i = 0; i < png_ptr->offset_table_count; i++)
+ {
+ if (ptr == png_ptr->offset_table_ptr[i])
+ {
+ ptr = NULL;
+ png_ptr->offset_table_count_free++;
+ break;
+ }
+ }
+ if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
+ {
+ farfree(png_ptr->offset_table);
+ farfree(png_ptr->offset_table_ptr);
+ png_ptr->offset_table = NULL;
+ png_ptr->offset_table_ptr = NULL;
+ }
+ }
+
+ if (ptr != NULL)
+ {
+ farfree(ptr);
+ }
+}
+
+#else /* Not the Borland DOS special memory handler */
+
+/* Allocate memory for a png_struct or a png_info. The malloc and
+ memset can be replaced by a single call to calloc() if this is thought
+ to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Allocate memory for a png_struct or a png_info. The malloc and
+ memset can be replaced by a single call to calloc() if this is thought
+ to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_size_t size;
+ png_voidp struct_ptr;
+
+ if (type == PNG_STRUCT_INFO)
+ size = png_sizeof(png_info);
+ else if (type == PNG_STRUCT_PNG)
+ size = png_sizeof(png_struct);
+ else
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(malloc_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ struct_ptr = (*(malloc_fn))(png_ptr, size);
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+ return (struct_ptr);
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ struct_ptr = (png_voidp)farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ struct_ptr = (png_voidp)halloc(size,1);
+# else
+ struct_ptr = (png_voidp)malloc(size);
+# endif
+#endif
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+
+ return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+ png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (struct_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(free_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ (*(free_fn))(png_ptr, struct_ptr);
+ return;
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ farfree(struct_ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ hfree(struct_ptr);
+# else
+ free(struct_ptr);
+# endif
+#endif
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ 64K. However, zlib may allocate more then 64K if you don't tell
+ it not to. See zconf.h and png.h for more information. zlib does
+ need to allocate exactly 64K, so whatever you call here must
+ have the ability to do that. */
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+ if(png_ptr->malloc_fn != NULL)
+ ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+ else
+ ret = (png_malloc_default(png_ptr, size));
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory!");
+ return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (size > (png_uint_32)65536L)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Cannot Allocate > 64K");
+ else
+#endif
+ return NULL;
+ }
+#endif
+
+ /* Check for overflow */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ if (size != (unsigned long)size)
+ ret = NULL;
+ else
+ ret = farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ if (size != (unsigned long)size)
+ ret = NULL;
+ else
+ ret = halloc(size, 1);
+# else
+ if (size != (size_t)size)
+ ret = NULL;
+ else
+ ret = malloc((size_t)size);
+# endif
+#endif
+
+#ifndef PNG_USER_MEM_SUPPORTED
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory");
+#endif
+
+ return (ret);
+}
+
+/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
+ without taking any action. */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ {
+ (*(png_ptr->free_fn))(png_ptr, ptr);
+ return;
+ }
+ else png_free_default(png_ptr, ptr);
+}
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ farfree(ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ hfree(ptr);
+# else
+ free(ptr);
+# endif
+#endif
+}
+
+#endif /* Not Borland DOS special memory handler */
+
+#if defined(PNG_1_0_X)
+# define png_malloc_warn png_malloc
+#else
+/* This function was added at libpng version 1.2.3. The png_malloc_warn()
+ * function will set up png_malloc() to issue a png_warning and return NULL
+ * instead of issuing a png_error, if it fails to allocate the requested
+ * memory.
+ */
+png_voidp PNGAPI
+png_malloc_warn(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ptr;
+ png_uint_32 save_flags;
+ if(png_ptr == NULL) return (NULL);
+
+ save_flags=png_ptr->flags;
+ png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+ ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
+ png_ptr->flags=save_flags;
+ return(ptr);
+}
+#endif
+
+png_voidp PNGAPI
+png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
+ png_uint_32 length)
+{
+ png_size_t size;
+
+ size = (png_size_t)length;
+ if ((png_uint_32)size != length)
+ png_error(png_ptr,"Overflow in png_memcpy_check.");
+
+ return(png_memcpy (s1, s2, size));
+}
+
+png_voidp PNGAPI
+png_memset_check (png_structp png_ptr, png_voidp s1, int value,
+ png_uint_32 length)
+{
+ png_size_t size;
+
+ size = (png_size_t)length;
+ if ((png_uint_32)size != length)
+ png_error(png_ptr,"Overflow in png_memset_check.");
+
+ return (png_memset (s1, value, size));
+
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+ malloc_fn, png_free_ptr free_fn)
+{
+ if(png_ptr != NULL) {
+ png_ptr->mem_ptr = mem_ptr;
+ png_ptr->malloc_fn = malloc_fn;
+ png_ptr->free_fn = free_fn;
+ }
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_structp png_ptr)
+{
+ if(png_ptr == NULL) return (NULL);
+ return ((png_voidp)png_ptr->mem_ptr);
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngpread.c b/kernel/kls_png/ksquirrel-libs-png/pngpread.c
new file mode 100644
index 0000000..3dd0f06
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngpread.c
@@ -0,0 +1,1773 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * Last changed in libpng 1.2.20 September 8, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* push model modes */
+#define PNG_READ_SIG_MODE 0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE 2
+#define PNG_SKIP_MODE 3
+#define PNG_READ_tEXt_MODE 4
+#define PNG_READ_zTXt_MODE 5
+#define PNG_READ_DONE_MODE 6
+#define PNG_READ_iTXt_MODE 7
+#define PNG_ERROR_MODE 8
+
+void PNGAPI
+png_process_data(png_structp png_ptr, png_infop info_ptr,
+ png_bytep buffer, png_size_t buffer_size)
+{
+ if(png_ptr == NULL) return;
+ png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+ while (png_ptr->buffer_size)
+ {
+ png_process_some_data(png_ptr, info_ptr);
+ }
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+{
+ if(png_ptr == NULL) return;
+ switch (png_ptr->process_mode)
+ {
+ case PNG_READ_SIG_MODE:
+ {
+ png_push_read_sig(png_ptr, info_ptr);
+ break;
+ }
+ case PNG_READ_CHUNK_MODE:
+ {
+ png_push_read_chunk(png_ptr, info_ptr);
+ break;
+ }
+ case PNG_READ_IDAT_MODE:
+ {
+ png_push_read_IDAT(png_ptr);
+ break;
+ }
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ case PNG_READ_tEXt_MODE:
+ {
+ png_push_read_tEXt(png_ptr, info_ptr);
+ break;
+ }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ case PNG_READ_zTXt_MODE:
+ {
+ png_push_read_zTXt(png_ptr, info_ptr);
+ break;
+ }
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ case PNG_READ_iTXt_MODE:
+ {
+ png_push_read_iTXt(png_ptr, info_ptr);
+ break;
+ }
+#endif
+ case PNG_SKIP_MODE:
+ {
+ png_push_crc_finish(png_ptr);
+ break;
+ }
+ default:
+ {
+ png_ptr->buffer_size = 0;
+ break;
+ }
+ }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature. It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
+
+ if (png_ptr->buffer_size < num_to_check)
+ {
+ num_to_check = png_ptr->buffer_size;
+ }
+
+ png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+ num_to_check);
+ png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ else
+ {
+ if (png_ptr->sig_bytes >= 8)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+ }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IHDR;
+ PNG_CONST PNG_IDAT;
+ PNG_CONST PNG_IEND;
+ PNG_CONST PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ PNG_CONST PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ PNG_CONST PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ PNG_CONST PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ PNG_CONST PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ PNG_CONST PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ PNG_CONST PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ PNG_CONST PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ PNG_CONST PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ PNG_CONST PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ PNG_CONST PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ PNG_CONST PNG_sCAL;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ PNG_CONST PNG_sRGB;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ PNG_CONST PNG_sPLT;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ PNG_CONST PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ PNG_CONST PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ PNG_CONST PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ PNG_CONST PNG_zTXt;
+#endif
+#if defined(PNG_READ_APNG_SUPPORTED)
+ PNG_CONST PNG_acTL;
+ PNG_CONST PNG_fcTL;
+ PNG_CONST PNG_fdAT;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+ /* First we make sure we have enough data for the 4 byte chunk name
+ * and the 4 byte chunk length before proceeding with decoding the
+ * chunk data. To fully decode each of these chunks, we also make
+ * sure we have enough data in the buffer for the 4 byte CRC at the
+ * end of every chunk (except IDAT, which is handled separately).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+ }
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ if (png_ptr->num_frames_read > 0 &&
+ png_ptr->num_frames_read < info_ptr->num_frames)
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ /* discard trailing IDATs for the first frame */
+ if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
+ png_error(png_ptr, "out of place IDAT");
+
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_crc_skip(png_ptr, png_ptr->push_length);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ return;
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_ensure_sequence_number(png_ptr, 4);
+
+ if (!(png_ptr->mode & PNG_HAVE_fcTL))
+ {
+ /* discard trailing fdATs for frames other than the first */
+ if (png_ptr->num_frames_read < 2)
+ png_error(png_ptr, "out of place fdAT");
+
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_crc_skip(png_ptr, png_ptr->push_length);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ return;
+ }
+ else
+ {
+ /* frame data follows */
+ png_ptr->idat_size = png_ptr->push_length - 4;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+
+ return;
+ }
+ }
+ else if(!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_read_reset(png_ptr);
+ png_ptr->mode &= ~PNG_HAVE_fcTL;
+
+ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
+
+ if (!(png_ptr->mode & PNG_HAVE_fcTL))
+ png_error(png_ptr, "missing required fcTL chunk");
+
+ png_read_reinit(png_ptr, info_ptr);
+ png_progressive_read_reset(png_ptr);
+
+ if (png_ptr->frame_info_fn != NULL)
+ (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
+
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+
+ return;
+ }
+ else
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_warning(png_ptr, "Skipped (ignored) a chunk "
+ "between APNG chunks");
+ png_push_crc_skip(png_ptr, png_ptr->push_length);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ return;
+ }
+
+ return;
+ }
+#endif /* PNG_READ_APNG_SUPPORTED */
+
+ if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ if(png_ptr->mode & PNG_AFTER_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+ png_ptr->process_mode = PNG_READ_DONE_MODE;
+ png_push_have_end(png_ptr, info_ptr);
+ }
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+ if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+ }
+ }
+#endif
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ {
+ /* If we reach an IDAT chunk, this means we have read all of the
+ * header chunks, and we can start reading the image (or if this
+ * is called after the image has been read - we have an error).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ if (png_ptr->push_length == 0)
+ return;
+
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_error(png_ptr, "Too many IDAT's found");
+ }
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ png_have_info(png_ptr, info_ptr);
+#endif
+ png_ptr->idat_size = png_ptr->push_length;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+ png_push_have_info(png_ptr, info_ptr);
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ return;
+ }
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_APNG_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_fdAT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif /* PNG_READ_APNG_SUPPORTED */
+ else
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
+{
+ png_ptr->process_mode = PNG_SKIP_MODE;
+ png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structp png_ptr)
+{
+ if (png_ptr->skip_length && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
+ save_size = (png_size_t)png_ptr->skip_length;
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->skip_length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
+ save_size = (png_size_t)png_ptr->skip_length;
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->skip_length)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+}
+
+void PNGAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+ png_bytep ptr;
+
+ if(png_ptr == NULL) return;
+ ptr = buffer;
+ if (png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->save_buffer_size)
+ save_size = length;
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+ length -= save_size;
+ ptr += save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->current_buffer_size)
+ save_size = length;
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structp png_ptr)
+{
+ if (png_ptr->save_buffer_size)
+ {
+ if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+ {
+ png_size_t i,istop;
+ png_bytep sp;
+ png_bytep dp;
+
+ istop = png_ptr->save_buffer_size;
+ for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+ i < istop; i++, sp++, dp++)
+ {
+ *dp = *sp;
+ }
+ }
+ }
+ if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+ png_ptr->save_buffer_max)
+ {
+ png_size_t new_max;
+ png_bytep old_buffer;
+
+ if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+ (png_ptr->current_buffer_size + 256))
+ {
+ png_error(png_ptr, "Potential overflow of save_buffer");
+ }
+ new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+ old_buffer = png_ptr->save_buffer;
+ png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)new_max);
+ png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ png_free(png_ptr, old_buffer);
+ png_ptr->save_buffer_max = new_max;
+ }
+ if (png_ptr->current_buffer_size)
+ {
+ png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+ png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+ png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+ png_ptr->current_buffer_size = 0;
+ }
+ png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+ png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ png_ptr->current_buffer = buffer;
+ png_ptr->current_buffer_size = buffer_length;
+ png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+ png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#if defined(PNG_READ_APNG_SUPPORTED)
+ PNG_fdAT;
+ PNG_IEND;
+#endif
+#endif
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+
+ if (png_ptr->buffer_size < 12)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_fdAT, 4)
+ && png_ptr->num_frames_read > 0)
+ {
+ if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ if (png_ptr->frame_end_fn != NULL)
+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
+ png_ptr->num_frames_read++;
+ return;
+ }
+ else
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ png_error(png_ptr, "Not enough image data");
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_warning(png_ptr, "Skipping (ignoring) a chunk between "
+ "APNG chunks");
+ png_crc_finish(png_ptr, png_ptr->push_length);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ return;
+ }
+ }
+ else
+#endif
+ if ( png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)
+ && (png_ptr->num_frames_read == 0) )
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_error(png_ptr, "Not enough compressed data");
+#if defined(PNG_READ_APNG_SUPPORTED)
+ if (png_ptr->frame_end_fn != NULL)
+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
+ png_ptr->num_frames_read++;
+#endif
+ return;
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ if(png_ptr->num_frames_read > 0)
+ {
+ png_ensure_sequence_number(png_ptr, 4);
+ png_ptr->idat_size -= 4;
+ }
+#endif
+ }
+ if (png_ptr->idat_size && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
+ {
+ save_size = (png_size_t)png_ptr->idat_size;
+ /* check for overflow */
+ if((png_uint_32)save_size != png_ptr->idat_size)
+ png_error(png_ptr, "save_size overflowed in pngpread");
+ }
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+ png_ptr->idat_size -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->idat_size && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
+ {
+ save_size = (png_size_t)png_ptr->idat_size;
+ /* check for overflow */
+ if((png_uint_32)save_size != png_ptr->idat_size)
+ png_error(png_ptr, "save_size overflowed in pngpread");
+ }
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->idat_size)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ int ret;
+
+ if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
+ png_error(png_ptr, "Extra compression data");
+
+ png_ptr->zstream.next_in = buffer;
+ png_ptr->zstream.avail_in = (uInt)buffer_length;
+ for(;;)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK)
+ {
+ if (ret == Z_STREAM_END)
+ {
+ if (png_ptr->zstream.avail_in)
+ png_error(png_ptr, "Extra compressed data");
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_push_process_row(png_ptr);
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ else if (ret == Z_BUF_ERROR)
+ break;
+ else
+ png_error(png_ptr, "Decompression Error");
+ }
+ if (!(png_ptr->zstream.avail_out))
+ {
+ if ((
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ png_ptr->interlaced && png_ptr->pass > 6) ||
+ (!png_ptr->interlaced &&
+#endif
+ png_ptr->row_number == png_ptr->num_rows))
+ {
+ if (png_ptr->zstream.avail_in)
+ png_warning(png_ptr, "Too much data in IDAT chunks");
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ png_push_process_row(png_ptr);
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ }
+ else
+ break;
+ }
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structp png_ptr)
+{
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->iwidth;
+ png_ptr->row_info.channels = png_ptr->channels;
+ png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+ png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+
+ png_read_filter_row(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+ (int)(png_ptr->row_buf[0]));
+
+ png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+ png_ptr->rowbytes + 1);
+
+ if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+ png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ /* blow up interlaced rows to full size */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+/* old interface (pre-1.0.9):
+ png_do_read_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+ png_do_read_interlace(png_ptr);
+
+ switch (png_ptr->pass)
+ {
+ case 0:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
+ }
+ if (png_ptr->pass == 2) /* pass 1 might be empty */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ if (png_ptr->pass == 4 && png_ptr->height <= 4)
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ if (png_ptr->pass == 6 && png_ptr->height <= 4)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ break;
+ }
+ case 1:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 2) /* skip top 4 generated rows */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ int i;
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 4) /* pass 3 might be empty */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ break;
+ }
+ case 3:
+ {
+ int i;
+ for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 4) /* skip top two generated rows */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ int i;
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 6) /* pass 5 might be empty */
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ break;
+ }
+ case 5:
+ {
+ int i;
+ for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 6) /* skip top generated row */
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ break;
+ }
+ case 6:
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ if (png_ptr->pass != 6)
+ break;
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+ /* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+ */
+#endif
+
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ png_memset_check(png_ptr, png_ptr->prev_row, 0,
+ png_ptr->rowbytes + 1);
+ do
+ {
+ png_ptr->pass++;
+ if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+ (png_ptr->pass == 3 && png_ptr->width < 3) ||
+ (png_ptr->pass == 5 && png_ptr->width < 2))
+ png_ptr->pass++;
+
+ if (png_ptr->pass > 7)
+ png_ptr->pass--;
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1;
+
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+ }
+}
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place tEXt");
+ info_ptr = info_ptr; /* to quiet some compiler warnings */
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ png_ptr->skip_length = 0; /* This may not be necessary */
+
+ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+ {
+ png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+ png_ptr->skip_length = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length+1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_tEXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+ else
+ text_size = png_ptr->current_text_left;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp text;
+ png_charp key;
+ int ret;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+ if (png_ptr->skip_length)
+ return;
+#endif
+
+ key = png_ptr->current_text;
+
+ for (text = key; *text; text++)
+ /* empty loop */ ;
+
+ if (text != key + png_ptr->current_text_size)
+ text++;
+
+ text_ptr = (png_textp)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+#endif
+ text_ptr->text = text;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+ png_ptr->current_text = NULL;
+
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store text chunk.");
+ }
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place zTXt");
+ info_ptr = info_ptr; /* to quiet some compiler warnings */
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We can't handle zTXt chunks > 64K, since we don't have enough space
+ * to be able to store the uncompressed data. Actually, the threshold
+ * is probably around 32K, but it isn't as definite as 64K is.
+ */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+ png_push_crc_skip(png_ptr, length);
+ return;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length+1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_zTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+ else
+ text_size = png_ptr->current_text_left;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp text;
+ png_charp key;
+ int ret;
+ png_size_t text_size, key_size;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+ key = png_ptr->current_text;
+
+ for (text = key; *text; text++)
+ /* empty loop */ ;
+
+ /* zTXt can't have zero text */
+ if (text == key + png_ptr->current_text_size)
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ return;
+ }
+
+ text++;
+
+ if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ return;
+ }
+
+ text++;
+
+ png_ptr->zstream.next_in = (png_bytep )text;
+ png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
+ (text - key));
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ key_size = text - key;
+ text_size = 0;
+ text = NULL;
+ ret = Z_STREAM_END;
+
+ while (png_ptr->zstream.avail_in)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ png_free(png_ptr, text);
+ return;
+ }
+ if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
+ {
+ if (text == NULL)
+ {
+ text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+ + key_size + 1));
+ png_memcpy(text + key_size, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ png_memcpy(text, key, key_size);
+ text_size = key_size + png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out;
+ *(text + text_size) = '\0';
+ }
+ else
+ {
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc(png_ptr, text_size +
+ (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+ + 1));
+ png_memcpy(text, tmp, text_size);
+ png_free(png_ptr, tmp);
+ png_memcpy(text + text_size, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ *(text + text_size) = '\0';
+ }
+ if (ret != Z_STREAM_END)
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ if (ret == Z_STREAM_END)
+ break;
+ }
+
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ if (ret != Z_STREAM_END)
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ png_free(png_ptr, text);
+ return;
+ }
+
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ key = text;
+ text += key_size;
+
+ text_ptr = (png_textp)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+#endif
+ text_ptr->text = text;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store text chunk.");
+ }
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place iTXt");
+ info_ptr = info_ptr; /* to quiet some compiler warnings */
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ png_ptr->skip_length = 0; /* This may not be necessary */
+
+ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+ {
+ png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+ png_ptr->skip_length = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length+1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+ else
+ text_size = png_ptr->current_text_left;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp key;
+ int comp_flag;
+ png_charp lang;
+ png_charp lang_key;
+ png_charp text;
+ int ret;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+ if (png_ptr->skip_length)
+ return;
+#endif
+
+ key = png_ptr->current_text;
+
+ for (lang = key; *lang; lang++)
+ /* empty loop */ ;
+
+ if (lang != key + png_ptr->current_text_size)
+ lang++;
+
+ comp_flag = *lang++;
+ lang++; /* skip comp_type, always zero */
+
+ for (lang_key = lang; *lang_key; lang_key++)
+ /* empty loop */ ;
+ lang_key++; /* skip NUL separator */
+
+ for (text = lang_key; *text; text++)
+ /* empty loop */ ;
+
+ if (text != key + png_ptr->current_text_size)
+ text++;
+
+ text_ptr = (png_textp)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ text_ptr->compression = comp_flag + 2;
+ text_ptr->key = key;
+ text_ptr->lang = lang;
+ text_ptr->lang_key = lang_key;
+ text_ptr->text = text;
+ text_ptr->text_length = 0;
+ text_ptr->itxt_length = png_strlen(text);
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_ptr->current_text = NULL;
+
+ png_free(png_ptr, text_ptr);
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
+ }
+}
+#endif
+
+/* This function is called when we haven't found a handler for this
+ * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
+ * name or a critical chunk), the chunk is (currently) silently ignored.
+ */
+void /* PRIVATE */
+png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ png_uint_32 skip=0;
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ {
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ && png_ptr->read_user_chunk_fn == NULL
+#endif
+ )
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+
+ info_ptr = info_ptr; /* to quiet some compiler warnings */
+ }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+ {
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "unknown chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+ png_strncpy((png_charp)png_ptr->unknown_chunk.name,
+ (png_charp)png_ptr->chunk_name,
+ png_sizeof((png_charp)png_ptr->chunk_name));
+ png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
+ png_ptr->unknown_chunk.size = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ if(png_ptr->read_user_chunk_fn != NULL)
+ {
+ /* callback to user unknown chunk handler */
+ int ret;
+ ret = (*(png_ptr->read_user_chunk_fn))
+ (png_ptr, &png_ptr->unknown_chunk);
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+ if (ret == 0)
+ {
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS)
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ }
+ }
+#else
+ png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+#endif
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+ else
+#endif
+ skip=length;
+ png_push_crc_skip(png_ptr, skip);
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->info_fn != NULL)
+ (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->end_fn != NULL)
+ (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structp png_ptr, png_bytep row)
+{
+ if (png_ptr->row_fn != NULL)
+ (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+ (int)png_ptr->pass);
+}
+
+void PNGAPI
+png_progressive_combine_row (png_structp png_ptr,
+ png_bytep old_row, png_bytep new_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST int FARDATA png_pass_dsp_mask[7] =
+ {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
+ if(png_ptr == NULL) return;
+ if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
+ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
+}
+
+void PNGAPI
+png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn)
+{
+ if(png_ptr == NULL) return;
+ png_ptr->info_fn = info_fn;
+ png_ptr->row_fn = row_fn;
+ png_ptr->end_fn = end_fn;
+
+ png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+void PNGAPI
+png_set_progressive_frame_fn(png_structp png_ptr,
+ png_progressive_frame_ptr frame_info_fn,
+ png_progressive_frame_ptr frame_end_fn)
+{
+ png_ptr->frame_info_fn = frame_info_fn;
+ png_ptr->frame_end_fn = frame_end_fn;
+}
+#endif
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_structp png_ptr)
+{
+ if(png_ptr == NULL) return (NULL);
+ return png_ptr->io_ptr;
+}
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngread.c b/kernel/kls_png/ksquirrel-libs-png/pngread.c
new file mode 100644
index 0000000..285c18d
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngread.c
@@ -0,0 +1,1604 @@
+
+/* pngread.c - read a PNG file
+ *
+ * Last changed in libpng 1.2.19 August 19, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED)
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ png_structp png_ptr;
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+
+ int i;
+
+ png_debug(1, "in png_create_read_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+ (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif
+ if (png_ptr == NULL)
+ return (NULL);
+
+ /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_ptr->jmpbuf))
+#endif
+ {
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf=NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr,
+ (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ return (NULL);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif
+
+ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+ i=0;
+ do
+ {
+ if(user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first digit.
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[80];
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "Incompatible libpng version in application and library");
+ }
+ }
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+ switch (inflateInit(&png_ptr->zstream))
+ {
+ case Z_OK: /* Do nothing */ break;
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
+ case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
+ default: png_error(png_ptr, "Unknown zlib error");
+ }
+
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then encounter
+ a png_error() will longjmp here. Since the jmpbuf is then meaningless we
+ abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+ PNG_ABORT();
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#else
+ if (setjmp(png_ptr->jmpbuf))
+ PNG_ABORT();
+#endif
+#endif
+ return (png_ptr);
+}
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Initialize PNG structure for reading, and allocate any memory needed.
+ This interface is deprecated in favour of the png_create_read_struct(),
+ and it will disappear as of libpng-1.3.0. */
+void PNGAPI
+png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size, png_size_t png_info_size)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+ if(png_ptr == NULL) return;
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ if(png_sizeof(png_struct) > png_struct_size ||
+ png_sizeof(png_info) > png_info_size)
+ {
+ char msg[80];
+ png_ptr->warning_fn=NULL;
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+ }
+#endif
+ if(png_sizeof(png_struct) > png_struct_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The png struct allocated by the application for reading is too small.");
+ }
+ if(png_sizeof(png_info) > png_info_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The info struct allocated by application for reading is too small.");
+ }
+ png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+#endif /* PNG_1_0_X || PNG_1_2_X */
+
+void PNGAPI
+png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+
+ int i=0;
+
+ png_structp png_ptr=*ptr_ptr;
+
+ if(png_ptr == NULL) return;
+
+ do
+ {
+ if(user_png_ver[i] != png_libpng_ver[i])
+ {
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+ png_ptr->warning_fn=NULL;
+ png_warning(png_ptr,
+ "Application uses deprecated png_read_init() and should be recompiled.");
+ break;
+#endif
+ }
+ } while (png_libpng_ver[i++]);
+
+ png_debug(1, "in png_read_init_3\n");
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* save jump buffer and error functions */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+ if(png_sizeof(png_struct) > png_struct_size)
+ {
+ png_destroy_struct(png_ptr);
+ *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+ png_ptr = *ptr_ptr;
+ }
+
+ /* reset all variables to 0 */
+ png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* restore jump buffer */
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+ /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+ switch (inflateInit(&png_ptr->zstream))
+ {
+ case Z_OK: /* Do nothing */ break;
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
+ case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
+ default: png_error(png_ptr, "Unknown zlib error");
+ }
+
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+}
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream. You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here. The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structp png_ptr, png_infop info_ptr)
+{
+ if(png_ptr == NULL) return;
+ png_debug(1, "in png_read_info\n");
+ /* If we haven't checked all of the PNG signature bytes, do so now. */
+ if (png_ptr->sig_bytes < 8)
+ {
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
+
+ png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+ png_ptr->sig_bytes = 8;
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ if (num_checked < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+ }
+
+ for(;;)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IHDR;
+ PNG_CONST PNG_IDAT;
+ PNG_CONST PNG_IEND;
+ PNG_CONST PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ PNG_CONST PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ PNG_CONST PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ PNG_CONST PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ PNG_CONST PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ PNG_CONST PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ PNG_CONST PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ PNG_CONST PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ PNG_CONST PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ PNG_CONST PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ PNG_CONST PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ PNG_CONST PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ PNG_CONST PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ PNG_CONST PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ PNG_CONST PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ PNG_CONST PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ PNG_CONST PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ PNG_CONST PNG_zTXt;
+#endif
+#if defined(PNG_READ_APNG_SUPPORTED)
+ PNG_CONST PNG_acTL;
+ PNG_CONST PNG_fcTL;
+ PNG_CONST PNG_fdAT;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+ png_byte chunk_length[4];
+ png_uint_32 length;
+
+ png_read_data(png_ptr, chunk_length, 4);
+ length = png_get_uint_31(png_ptr,chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+ png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
+ length);
+
+ /* This should be a binary subdivision search or a hash for
+ * matching the chunk name rather than a linear search.
+ */
+ if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ if(png_ptr->mode & PNG_AFTER_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ png_handle_IHDR(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_handle_unknown(png_ptr, info_ptr, length);
+ if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+ break;
+ }
+ }
+#endif
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_handle_PLTE(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ png_have_info(png_ptr, info_ptr);
+#endif
+ png_ptr->idat_size = length;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ break;
+ }
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_APNG_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
+ png_handle_acTL(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
+ png_handle_fcTL(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
+ png_handle_fdAT(png_ptr, info_ptr, length);
+#endif
+ else
+ png_handle_unknown(png_ptr, info_ptr, length);
+ }
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+void PNGAPI
+png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
+{
+ png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
+
+ png_debug(0, "Reading frame head\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_acTL))
+ png_error(png_ptr, "attempt to png_read_frame_head() but "
+ "no acTL present");
+
+ /* do nothing for the main IDAT */
+ if (png_ptr->num_frames_read == 0)
+ return;
+
+ png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
+
+ png_read_reset(png_ptr);
+ png_ptr->mode &= ~PNG_HAVE_fcTL;
+
+ have_chunk_after_DAT = 0;
+ for (;;)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+ PNG_fdAT;
+ PNG_fcTL;
+#endif
+ png_byte chunk_length[4];
+ png_uint_32 length;
+
+ png_read_data(png_ptr, chunk_length, 4);
+ length = png_get_uint_31(png_ptr, chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ /* discard trailing IDATs for the first frame */
+ if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
+ png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
+ png_crc_finish(png_ptr, length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
+ {
+ png_handle_fcTL(png_ptr, info_ptr, length);
+ have_chunk_after_DAT = 1;
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
+ {
+ png_ensure_sequence_number(png_ptr, length);
+
+ /* discard trailing fdATs for frames other than the first */
+ if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
+ png_crc_finish(png_ptr, length - 4);
+ else if(png_ptr->mode & PNG_HAVE_fcTL)
+ {
+ png_ptr->idat_size = length - 4;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ break;
+ }
+ else
+ png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
+ }
+ else
+ {
+ png_warning(png_ptr, "Skipped (ignored) a chunk "
+ "between APNG chunks");
+ png_crc_finish(png_ptr, length);
+ }
+ }
+}
+#endif /* PNG_READ_APNG_SUPPORTED */
+
+/* optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_update_info\n");
+ if(png_ptr == NULL) return;
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+ else
+ png_warning(png_ptr,
+ "Ignoring extra png_read_update_info() call; row buffer not reallocated");
+ png_read_transform_info(png_ptr, info_ptr);
+}
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place. This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structp png_ptr)
+{
+ png_debug(1, "in png_start_read_image\n");
+ if(png_ptr == NULL) return;
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+void PNGAPI
+png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IDAT;
+#if defined(PNG_READ_APNG_SUPPORTED)
+ PNG_CONST PNG_fdAT;
+ PNG_CONST PNG_IEND;
+#endif
+ PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
+ 0xff};
+ PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+#endif
+ int ret;
+ if(png_ptr == NULL) return;
+ png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
+ png_ptr->row_number, png_ptr->pass);
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
+#endif
+ }
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ /* if interlaced and we do not need a new row, combine row and return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 4))
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 3:
+ if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 4:
+ if ((png_ptr->row_number & 3) != 2)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 2))
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 5:
+ if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 6:
+ if (!(png_ptr->row_number & 1))
+ {
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "Invalid attempt to read row data");
+
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+ do
+ {
+ if (!(png_ptr->zstream.avail_in))
+ {
+ png_uint_32 bytes_to_skip = 0;
+
+ while (!png_ptr->idat_size || bytes_to_skip != 0)
+ {
+ png_byte chunk_length[4];
+
+ png_crc_finish(png_ptr, bytes_to_skip);
+ bytes_to_skip = 0;
+
+ png_read_data(png_ptr, chunk_length, 4);
+ png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ if (png_ptr->num_frames_read == 0)
+ {
+#endif
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_error(png_ptr, "Not enough image data");
+#if defined(PNG_READ_APNG_SUPPORTED)
+ }
+ else
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ png_error(png_ptr, "Not enough image data");
+ if (png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
+ {
+ png_warning(png_ptr, "Skipped (ignored) a chunk "
+ "between APNG chunks");
+ bytes_to_skip = png_ptr->idat_size;
+ continue;
+ }
+
+ png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
+
+ png_ptr->idat_size -= 4;
+ }
+#endif
+ }
+ png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_in = png_ptr->zbuf;
+ if (png_ptr->zbuf_size > png_ptr->idat_size)
+ png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+ png_crc_read(png_ptr, png_ptr->zbuf,
+ (png_size_t)png_ptr->zstream.avail_in);
+ png_ptr->idat_size -= png_ptr->zstream.avail_in;
+ }
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret == Z_STREAM_END)
+ {
+ if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
+ png_ptr->idat_size)
+ png_error(png_ptr, "Extra compressed data");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+#if defined(PNG_READ_APNG_SUPPORTED)
+ png_ptr->num_frames_read++;
+#endif
+ break;
+ }
+ if (ret != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+ "Decompression error");
+
+ } while (png_ptr->zstream.avail_out);
+
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->iwidth;
+ png_ptr->row_info.channels = png_ptr->channels;
+ png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+ png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+
+ if(png_ptr->row_buf[0])
+ png_read_filter_row(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+ (int)(png_ptr->row_buf[0]));
+
+ png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+ png_ptr->rowbytes + 1);
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+ }
+#endif
+
+
+ if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+ png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ /* blow up interlaced rows to full size */
+ if (png_ptr->interlaced &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+/* old interface (pre-1.0.9):
+ png_do_read_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+ png_do_read_interlace(png_ptr);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ if (row != NULL)
+ png_combine_row(png_ptr, row,
+ png_pass_mask[png_ptr->pass]);
+ }
+ else
+#endif
+ {
+ if (row != NULL)
+ png_combine_row(png_ptr, row, 0xff);
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 0xff);
+ }
+ png_read_finish_row(png_ptr);
+
+ if (png_ptr->read_row_fn != NULL)
+ (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass. If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive. If the image is displayed after each pass, it will
+ * appear to "sparkle" in. "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available. If you do not want this "chunky" display, you may pass
+ * NULL for display_row. If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows. In this case, you do not have to provide a display_row buffer
+ * also, but you may. If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+
+void PNGAPI
+png_read_rows(png_structp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows)
+{
+ png_uint_32 i;
+ png_bytepp rp;
+ png_bytepp dp;
+
+ png_debug(1, "in png_read_rows\n");
+ if(png_ptr == NULL) return;
+ rp = row;
+ dp = display_row;
+ if (rp != NULL && dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp++;
+ png_bytep dptr = *dp++;
+
+ png_read_row(png_ptr, rptr, dptr);
+ }
+ else if(rp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp;
+ png_read_row(png_ptr, rptr, png_bytep_NULL);
+ rp++;
+ }
+ else if(dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep dptr = *dp;
+ png_read_row(png_ptr, png_bytep_NULL, dptr);
+ dp++;
+ }
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image. If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been. You can
+ * only call this function once. If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+void PNGAPI
+png_read_image(png_structp png_ptr, png_bytepp image)
+{
+ png_uint_32 i,image_height;
+ int pass, j;
+ png_bytepp rp;
+
+ png_debug(1, "in png_read_image\n");
+ if(png_ptr == NULL) return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ pass = png_set_interlace_handling(png_ptr);
+#else
+ if (png_ptr->interlaced)
+ png_error(png_ptr,
+ "Cannot read interlaced image -- interlace handler disabled.");
+ pass = 1;
+#endif
+
+
+ image_height=png_ptr->height;
+ png_ptr->num_rows = image_height; /* Make sure this is set correctly */
+
+ for (j = 0; j < pass; j++)
+ {
+ rp = image;
+ for (i = 0; i < image_height; i++)
+ {
+ png_read_row(png_ptr, *rp, png_bytep_NULL);
+ rp++;
+ }
+ }
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structp png_ptr, png_infop info_ptr)
+{
+ png_byte chunk_length[4];
+ png_uint_32 length;
+
+ png_debug(1, "in png_read_end\n");
+ if(png_ptr == NULL) return;
+ png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
+
+ do
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IHDR;
+ PNG_CONST PNG_IDAT;
+ PNG_CONST PNG_IEND;
+ PNG_CONST PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ PNG_CONST PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ PNG_CONST PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ PNG_CONST PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ PNG_CONST PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ PNG_CONST PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ PNG_CONST PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ PNG_CONST PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ PNG_CONST PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ PNG_CONST PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ PNG_CONST PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ PNG_CONST PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ PNG_CONST PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ PNG_CONST PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ PNG_CONST PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ PNG_CONST PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ PNG_CONST PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ PNG_CONST PNG_zTXt;
+#endif
+#if defined(PNG_READ_APNG_SUPPORTED)
+ PNG_CONST PNG_acTL;
+ PNG_CONST PNG_fcTL;
+ PNG_CONST PNG_fdAT;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+
+ png_read_data(png_ptr, chunk_length, 4);
+ length = png_get_uint_31(png_ptr,chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+ png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ png_handle_IHDR(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_error(png_ptr, "Too many IDAT's found");
+ }
+ png_handle_unknown(png_ptr, info_ptr, length);
+ if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+#endif
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ /* Zero length IDATs are legal after the last IDAT has been
+ * read, but not after other chunks have been read.
+ */
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_error(png_ptr, "Too many IDAT's found");
+ png_crc_finish(png_ptr, length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_handle_PLTE(png_ptr, info_ptr, length);
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_APNG_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
+ png_handle_acTL(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
+ png_handle_fcTL(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
+ png_handle_fdAT(png_ptr, info_ptr, length);
+#endif
+ else
+ png_handle_unknown(png_ptr, info_ptr, length);
+ } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+/* free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+ png_infopp end_info_ptr_ptr)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL, end_info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+ png_voidp mem_ptr;
+#endif
+
+ png_debug(1, "in png_destroy_read_struct\n");
+ if (png_ptr_ptr != NULL)
+ png_ptr = *png_ptr_ptr;
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (end_info_ptr_ptr != NULL)
+ end_info_ptr = *end_info_ptr_ptr;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+#endif
+
+ png_read_destroy(png_ptr, info_ptr, end_info_ptr);
+
+ if (info_ptr != NULL)
+ {
+#if defined(PNG_TEXT_SUPPORTED)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+
+ if (end_info_ptr != NULL)
+ {
+#if defined(PNG_READ_TEXT_SUPPORTED)
+ png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
+#endif
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)end_info_ptr);
+#endif
+ *end_info_ptr_ptr = NULL;
+ }
+
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ *png_ptr_ptr = NULL;
+ }
+}
+
+/* free all memory used by the read (old method) */
+void /* PRIVATE */
+png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp;
+#endif
+ png_error_ptr error_fn;
+ png_error_ptr warning_fn;
+ png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+#endif
+
+ png_debug(1, "in png_read_destroy\n");
+ if (info_ptr != NULL)
+ png_info_destroy(png_ptr, info_ptr);
+
+ if (end_info_ptr != NULL)
+ png_info_destroy(png_ptr, end_info_ptr);
+
+ png_free(png_ptr, png_ptr->zbuf);
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->prev_row);
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ png_free(png_ptr, png_ptr->palette_lookup);
+ png_free(png_ptr, png_ptr->dither_index);
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ png_free(png_ptr, png_ptr->gamma_table);
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_free(png_ptr, png_ptr->gamma_from_1);
+ png_free(png_ptr, png_ptr->gamma_to_1);
+#endif
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->free_me &= ~PNG_FREE_PLTE;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+#if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans);
+ png_ptr->free_me &= ~PNG_FREE_TRNS;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans);
+ png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_HIST)
+ png_free(png_ptr, png_ptr->hist);
+ png_ptr->free_me &= ~PNG_FREE_HIST;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_HIST)
+ png_free(png_ptr, png_ptr->hist);
+ png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (png_ptr->gamma_16_table != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_table[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_table);
+ }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_from_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_from_1);
+ }
+ if (png_ptr->gamma_16_to_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_to_1);
+ }
+#endif
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+ inflateEnd(&png_ptr->zstream);
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+#ifdef PNG_TEXT_SUPPORTED
+ png_free(png_ptr, png_ptr->current_text);
+#endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+ /* Save the important info out of the png_struct, in case it is
+ * being used again.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+ error_fn = png_ptr->error_fn;
+ warning_fn = png_ptr->warning_fn;
+ error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+#endif
+
+ png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+ png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
+{
+ if(png_ptr == NULL) return;
+ png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_read_png(png_structp png_ptr, png_infop info_ptr,
+ int transforms,
+ voidp params)
+{
+ int row;
+
+ if(png_ptr == NULL) return;
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+ /* invert the alpha channel from opacity to transparency
+ */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* png_read_info() gives us all of the information from the
+ * PNG file before the first IDAT (image data chunk).
+ */
+ png_read_info(png_ptr, info_ptr);
+ if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+ png_error(png_ptr,"Image is too high to process with png_read_png()");
+
+ /* -------------- image transformations start here ------------------- */
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ /* tell libpng to strip 16 bit/color files down to 8 bits per color
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_16)
+ png_set_strip_16(png_ptr);
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ /* Strip alpha bytes from the input data without combining with
+ * the background (not recommended).
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+ png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+ /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ /* Change the order of packed pixels to least significant bit first
+ * (not useful if you are using png_set_packing).
+ */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ /* Expand paletted colors into true RGB triplets
+ * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+ * Expand paletted or RGB images with transparency to full alpha
+ * channels so the data will be available as RGBA quartets.
+ */
+ if (transforms & PNG_TRANSFORM_EXPAND)
+ if ((png_ptr->bit_depth < 8) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+ (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+ png_set_expand(png_ptr);
+#endif
+
+ /* We don't handle background color or gamma transformation or dithering.
+ */
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+ /* invert monochrome files to have 0 as white and 1 as black
+ */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+ /* If you want to shift the pixel values from the range [0,255] or
+ * [0,65535] to the original [0,7] or [0,31], or whatever range the
+ * colors were originally in:
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+ {
+ png_color_8p sig_bit;
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, sig_bit);
+ }
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+ /* flip the RGB pixels to BGR (or RGBA to BGRA)
+ */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+ /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
+ */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+ /* swap bytes of 16 bit files to least significant byte first
+ */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+ /* We don't handle adding filler bytes */
+
+ /* Optional call to gamma correct and add the background to the palette
+ * and update info structure. REQUIRED if you are expecting libpng to
+ * update the palette for you (i.e., you selected such a transform above).
+ */
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* -------------- image transformations end here ------------------- */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+#endif
+ if(info_ptr->row_pointers == NULL)
+ {
+ info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+ info_ptr->height * png_sizeof(png_bytep));
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_ROWS;
+#endif
+ for (row = 0; row < (int)info_ptr->height; row++)
+ {
+ info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr));
+ }
+ }
+
+ png_read_image(png_ptr, info_ptr->row_pointers);
+ info_ptr->valid |= PNG_INFO_IDAT;
+
+ /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ transforms = transforms; /* quiet compiler warnings */
+ params = params;
+
+}
+#endif /* PNG_INFO_IMAGE_SUPPORTED */
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngrio.c b/kernel/kls_png/ksquirrel-libs-png/pngrio.c
new file mode 100644
index 0000000..7d2522f
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngrio.c
@@ -0,0 +1,167 @@
+
+/* pngrio.c - functions for data input
+ *
+ * Last changed in libpng 1.2.13 November 13, 2006
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2006 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all input. Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method. Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED)
+
+/* Read the data from whatever input you are using. The default routine
+ reads from a file pointer. Note that this routine sometimes gets called
+ with very small lengths, so you should implement some kind of simple
+ buffering if you are using unbuffered reads. This should never be asked
+ to read more then 64K on a 16 bit machine. */
+void /* PRIVATE */
+png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_debug1(4,"reading %d bytes\n", (int)length);
+ if (png_ptr->read_data_fn != NULL)
+ (*(png_ptr->read_data_fn))(png_ptr, data, length);
+ else
+ png_error(png_ptr, "Call to NULL read function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function that does the actual reading of data. If you are
+ not reading from a standard C stream, you should create a replacement
+ read_data function and use it at run time with png_set_read_fn(), rather
+ than changing the library. */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ if(png_ptr == NULL) return;
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+#if defined(_WIN32_WCE)
+ if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = (png_size_t)fread(data, (png_size_t)1, length,
+ (png_FILE_p)png_ptr->io_ptr);
+#endif
+
+ if (check != length)
+ png_error(png_ptr, "Read Error");
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ int check;
+ png_byte *n_data;
+ png_FILE_p io_ptr;
+
+ if(png_ptr == NULL) return;
+ /* Check if data really is near. If so, use usual code. */
+ n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)n_data == data)
+ {
+#if defined(_WIN32_WCE)
+ if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fread(n_data, 1, length, io_ptr);
+#endif
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t read, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ read = MIN(NEAR_BUF_SIZE, remaining);
+#if defined(_WIN32_WCE)
+ if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
+ err = 0;
+#else
+ err = fread(buf, (png_size_t)1, read, io_ptr);
+#endif
+ png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+ if(err != read)
+ break;
+ else
+ check += err;
+ data += read;
+ remaining -= read;
+ }
+ while (remaining != 0);
+ }
+ if ((png_uint_32)check != (png_uint_32)length)
+ png_error(png_ptr, "read Error");
+}
+#endif
+#endif
+
+/* This function allows the application to supply a new input function
+ for libpng if standard C streams aren't being used.
+
+ This function takes as its arguments:
+ png_ptr - pointer to a png input data structure
+ io_ptr - pointer to user supplied structure containing info about
+ the input functions. May be NULL.
+ read_data_fn - pointer to a new input function that takes as its
+ arguments a pointer to a png_struct, a pointer to
+ a location where input data can be stored, and a 32-bit
+ unsigned int that is the number of bytes to be read.
+ To exit and output any fatal error messages the new write
+ function should call png_error(png_ptr, "Error msg"). */
+void PNGAPI
+png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn)
+{
+ if(png_ptr == NULL) return;
+ png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+ if (read_data_fn != NULL)
+ png_ptr->read_data_fn = read_data_fn;
+ else
+ png_ptr->read_data_fn = png_default_read_data;
+#else
+ png_ptr->read_data_fn = read_data_fn;
+#endif
+
+ /* It is an error to write to a read device */
+ if (png_ptr->write_data_fn != NULL)
+ {
+ png_ptr->write_data_fn = NULL;
+ png_warning(png_ptr,
+ "It's an error to set both read_data_fn and write_data_fn in the ");
+ png_warning(png_ptr,
+ "same structure. Resetting write_data_fn to NULL.");
+ }
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ png_ptr->output_flush_fn = NULL;
+#endif
+}
+#endif /* PNG_READ_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngrtran.c b/kernel/kls_png/ksquirrel-libs-png/pngrtran.c
new file mode 100644
index 0000000..97f12e6
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngrtran.c
@@ -0,0 +1,4284 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * Last changed in libpng 1.2.19 August 19, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED)
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
+{
+ png_debug(1, "in png_set_crc_action\n");
+ /* Tell libpng how we react to CRC errors in critical chunks */
+ if(png_ptr == NULL) return;
+ switch (crit_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* leave setting as is */
+ break;
+ case PNG_CRC_WARN_USE: /* warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+ break;
+ case PNG_CRC_QUIET_USE: /* quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+ PNG_FLAG_CRC_CRITICAL_IGNORE;
+ break;
+ case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
+ png_warning(png_ptr, "Can't discard critical data on CRC error.");
+ case PNG_CRC_ERROR_QUIT: /* error/quit */
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ break;
+ }
+
+ switch (ancil_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* leave setting as is */
+ break;
+ case PNG_CRC_WARN_USE: /* warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+ break;
+ case PNG_CRC_QUIET_USE: /* quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+ PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+ case PNG_CRC_ERROR_QUIT: /* error/quit */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+ case PNG_CRC_WARN_DISCARD: /* warn/discard data */
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ break;
+ }
+}
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+/* handle alpha and tRNS via a background color */
+void PNGAPI
+png_set_background(png_structp png_ptr,
+ png_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma)
+{
+ png_debug(1, "in png_set_background\n");
+ if(png_ptr == NULL) return;
+ if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+ {
+ png_warning(png_ptr, "Application must supply a known background gamma");
+ return;
+ }
+
+ png_ptr->transformations |= PNG_BACKGROUND;
+ png_memcpy(&(png_ptr->background), background_color,
+ png_sizeof(png_color_16));
+ png_ptr->background_gamma = (float)background_gamma;
+ png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+ png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip 16 bit depth files to 8 bit depth */
+void PNGAPI
+png_set_strip_16(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_strip_16\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_strip_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_strip_alpha\n");
+ if(png_ptr == NULL) return;
+ png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Dither file to 8 bit. Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible. If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number. "full_dither" indicates
+ * whether we need a dithering cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+ struct png_dsort_struct FAR * next;
+ png_byte left;
+ png_byte right;
+} png_dsort;
+typedef png_dsort FAR * png_dsortp;
+typedef png_dsort FAR * FAR * png_dsortpp;
+
+void PNGAPI
+png_set_dither(png_structp png_ptr, png_colorp palette,
+ int num_palette, int maximum_colors, png_uint_16p histogram,
+ int full_dither)
+{
+ png_debug(1, "in png_set_dither\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_DITHER;
+
+ if (!full_dither)
+ {
+ int i;
+
+ png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof (png_byte)));
+ for (i = 0; i < num_palette; i++)
+ png_ptr->dither_index[i] = (png_byte)i;
+ }
+
+ if (num_palette > maximum_colors)
+ {
+ if (histogram != NULL)
+ {
+ /* This is easy enough, just throw out the least used colors.
+ Perhaps not the best solution, but good enough. */
+
+ int i;
+
+ /* initialize an array to sort colors */
+ png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof (png_byte)));
+
+ /* initialize the dither_sort array */
+ for (i = 0; i < num_palette; i++)
+ png_ptr->dither_sort[i] = (png_byte)i;
+
+ /* Find the least used palette entries by starting a
+ bubble sort, and running it until we have sorted
+ out enough colors. Note that we don't care about
+ sorting all the colors, just finding which are
+ least used. */
+
+ for (i = num_palette - 1; i >= maximum_colors; i--)
+ {
+ int done; /* to stop early if the list is pre-sorted */
+ int j;
+
+ done = 1;
+ for (j = 0; j < i; j++)
+ {
+ if (histogram[png_ptr->dither_sort[j]]
+ < histogram[png_ptr->dither_sort[j + 1]])
+ {
+ png_byte t;
+
+ t = png_ptr->dither_sort[j];
+ png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
+ png_ptr->dither_sort[j + 1] = t;
+ done = 0;
+ }
+ }
+ if (done)
+ break;
+ }
+
+ /* swap the palette around, and set up a table, if necessary */
+ if (full_dither)
+ {
+ int j = num_palette;
+
+ /* put all the useful colors within the max, but don't
+ move the others */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+ {
+ do
+ j--;
+ while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+ palette[i] = palette[j];
+ }
+ }
+ }
+ else
+ {
+ int j = num_palette;
+
+ /* move all the used colors inside the max limit, and
+ develop a translation table */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ /* only move the colors we need to */
+ if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+ {
+ png_color tmp_color;
+
+ do
+ j--;
+ while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+
+ tmp_color = palette[j];
+ palette[j] = palette[i];
+ palette[i] = tmp_color;
+ /* indicate where the color went */
+ png_ptr->dither_index[j] = (png_byte)i;
+ png_ptr->dither_index[i] = (png_byte)j;
+ }
+ }
+
+ /* find closest color for those colors we are not using */
+ for (i = 0; i < num_palette; i++)
+ {
+ if ((int)png_ptr->dither_index[i] >= maximum_colors)
+ {
+ int min_d, k, min_k, d_index;
+
+ /* find the closest color to one we threw out */
+ d_index = png_ptr->dither_index[i];
+ min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+ for (k = 1, min_k = 0; k < maximum_colors; k++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+ if (d < min_d)
+ {
+ min_d = d;
+ min_k = k;
+ }
+ }
+ /* point to closest color */
+ png_ptr->dither_index[i] = (png_byte)min_k;
+ }
+ }
+ }
+ png_free(png_ptr, png_ptr->dither_sort);
+ png_ptr->dither_sort=NULL;
+ }
+ else
+ {
+ /* This is much harder to do simply (and quickly). Perhaps
+ we need to go through a median cut routine, but those
+ don't always behave themselves with only a few colors
+ as input. So we will just find the closest two colors,
+ and throw out one of them (chosen somewhat randomly).
+ [We don't understand this at all, so if someone wants to
+ work on improving it, be our guest - AED, GRP]
+ */
+ int i;
+ int max_d;
+ int num_new_palette;
+ png_dsortp t;
+ png_dsortpp hash;
+
+ t=NULL;
+
+ /* initialize palette index arrays */
+ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof (png_byte)));
+ png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof (png_byte)));
+
+ /* initialize the sort array */
+ for (i = 0; i < num_palette; i++)
+ {
+ png_ptr->index_to_palette[i] = (png_byte)i;
+ png_ptr->palette_to_index[i] = (png_byte)i;
+ }
+
+ hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
+ png_sizeof (png_dsortp)));
+ for (i = 0; i < 769; i++)
+ hash[i] = NULL;
+/* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
+
+ num_new_palette = num_palette;
+
+ /* initial wild guess at how far apart the farthest pixel
+ pair we will be eliminating will be. Larger
+ numbers mean more areas will be allocated, Smaller
+ numbers run the risk of not saving enough data, and
+ having to do this all over again.
+
+ I have not done extensive checking on this number.
+ */
+ max_d = 96;
+
+ while (num_new_palette > maximum_colors)
+ {
+ for (i = 0; i < num_new_palette - 1; i++)
+ {
+ int j;
+
+ for (j = i + 1; j < num_new_palette; j++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+ if (d <= max_d)
+ {
+
+ t = (png_dsortp)png_malloc_warn(png_ptr,
+ (png_uint_32)(png_sizeof(png_dsort)));
+ if (t == NULL)
+ break;
+ t->next = hash[d];
+ t->left = (png_byte)i;
+ t->right = (png_byte)j;
+ hash[d] = t;
+ }
+ }
+ if (t == NULL)
+ break;
+ }
+
+ if (t != NULL)
+ for (i = 0; i <= max_d; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p;
+
+ for (p = hash[i]; p; p = p->next)
+ {
+ if ((int)png_ptr->index_to_palette[p->left]
+ < num_new_palette &&
+ (int)png_ptr->index_to_palette[p->right]
+ < num_new_palette)
+ {
+ int j, next_j;
+
+ if (num_new_palette & 0x01)
+ {
+ j = p->left;
+ next_j = p->right;
+ }
+ else
+ {
+ j = p->right;
+ next_j = p->left;
+ }
+
+ num_new_palette--;
+ palette[png_ptr->index_to_palette[j]]
+ = palette[num_new_palette];
+ if (!full_dither)
+ {
+ int k;
+
+ for (k = 0; k < num_palette; k++)
+ {
+ if (png_ptr->dither_index[k] ==
+ png_ptr->index_to_palette[j])
+ png_ptr->dither_index[k] =
+ png_ptr->index_to_palette[next_j];
+ if ((int)png_ptr->dither_index[k] ==
+ num_new_palette)
+ png_ptr->dither_index[k] =
+ png_ptr->index_to_palette[j];
+ }
+ }
+
+ png_ptr->index_to_palette[png_ptr->palette_to_index
+ [num_new_palette]] = png_ptr->index_to_palette[j];
+ png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+ = png_ptr->palette_to_index[num_new_palette];
+
+ png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
+ png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ }
+
+ for (i = 0; i < 769; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p = hash[i];
+ while (p)
+ {
+ t = p->next;
+ png_free(png_ptr, p);
+ p = t;
+ }
+ }
+ hash[i] = 0;
+ }
+ max_d += 96;
+ }
+ png_free(png_ptr, hash);
+ png_free(png_ptr, png_ptr->palette_to_index);
+ png_free(png_ptr, png_ptr->index_to_palette);
+ png_ptr->palette_to_index=NULL;
+ png_ptr->index_to_palette=NULL;
+ }
+ num_palette = maximum_colors;
+ }
+ if (png_ptr->palette == NULL)
+ {
+ png_ptr->palette = palette;
+ }
+ png_ptr->num_palette = (png_uint_16)num_palette;
+
+ if (full_dither)
+ {
+ int i;
+ png_bytep distance;
+ int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
+ PNG_DITHER_BLUE_BITS;
+ int num_red = (1 << PNG_DITHER_RED_BITS);
+ int num_green = (1 << PNG_DITHER_GREEN_BITS);
+ int num_blue = (1 << PNG_DITHER_BLUE_BITS);
+ png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+ png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
+ (png_uint_32)(num_entries * png_sizeof (png_byte)));
+
+ png_memset(png_ptr->palette_lookup, 0, num_entries *
+ png_sizeof (png_byte));
+
+ distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+ png_sizeof(png_byte)));
+
+ png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
+
+ for (i = 0; i < num_palette; i++)
+ {
+ int ir, ig, ib;
+ int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
+ int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
+ int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
+
+ for (ir = 0; ir < num_red; ir++)
+ {
+ /* int dr = abs(ir - r); */
+ int dr = ((ir > r) ? ir - r : r - ir);
+ int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
+
+ for (ig = 0; ig < num_green; ig++)
+ {
+ /* int dg = abs(ig - g); */
+ int dg = ((ig > g) ? ig - g : g - ig);
+ int dt = dr + dg;
+ int dm = ((dr > dg) ? dr : dg);
+ int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
+
+ for (ib = 0; ib < num_blue; ib++)
+ {
+ int d_index = index_g | ib;
+ /* int db = abs(ib - b); */
+ int db = ((ib > b) ? ib - b : b - ib);
+ int dmax = ((dm > db) ? dm : db);
+ int d = dmax + dt + db;
+
+ if (d < (int)distance[d_index])
+ {
+ distance[d_index] = (png_byte)d;
+ png_ptr->palette_lookup[d_index] = (png_byte)i;
+ }
+ }
+ }
+ }
+ }
+
+ png_free(png_ptr, distance);
+ }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Transform the image from the file_gamma to the screen_gamma. We
+ * only do transformations on images where the file_gamma and screen_gamma
+ * are not close reciprocals, otherwise it slows things down slightly, and
+ * also needlessly introduces small errors.
+ *
+ * We will turn off gamma transformation later if no semitransparent entries
+ * are present in the tRNS array for palette images. We can't do it here
+ * because we don't necessarily have the tRNS chunk yet.
+ */
+void PNGAPI
+png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
+{
+ png_debug(1, "in png_set_gamma\n");
+ if(png_ptr == NULL) return;
+ if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ png_ptr->transformations |= PNG_GAMMA;
+ png_ptr->gamma = (float)file_gamma;
+ png_ptr->screen_gamma = (float)scrn_gamma;
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
+#endif
+}
+
+/* GRR 19990627: the following three functions currently are identical
+ * to png_set_expand(). However, it is entirely reasonable that someone
+ * might wish to expand an indexed image to RGB but *not* expand a single,
+ * fully transparent palette entry to a full alpha channel--perhaps instead
+ * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ * the transparent color with a particular RGB value, or drop tRNS entirely.
+ * IOW, a future version of the library may make the transformations flag
+ * a bit more fine-grained, with separate bits for each of these three
+ * functions.
+ *
+ * More to the point, these functions make it obvious what libpng will be
+ * doing, whereas "expand" can (and does) mean any number of things.
+ *
+ * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
+ * to expand only the sample depth but not to expand the tRNS to alpha.
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_palette_to_rgb\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
+#endif
+}
+
+#if !defined(PNG_1_0_X)
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_EXPAND;
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
+#endif
+}
+#endif
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+/* Deprecated as of libpng-1.2.9 */
+void PNGAPI
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_gray_1_2_4_to_8\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif
+
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_tRNS_to_alpha\n");
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
+#endif
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+void PNGAPI
+png_set_gray_to_rgb(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_gray_to_rgb\n");
+ png_ptr->transformations |= PNG_GRAY_TO_RGB;
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Convert a RGB image to a grayscale of the same width. This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+ double green)
+{
+ int red_fixed = (int)((float)red*100000.0 + 0.5);
+ int green_fixed = (int)((float)green*100000.0 + 0.5);
+ if(png_ptr == NULL) return;
+ png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
+}
+#endif
+
+void PNGAPI
+png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
+ png_fixed_point red, png_fixed_point green)
+{
+ png_debug(1, "in png_set_rgb_to_gray\n");
+ if(png_ptr == NULL) return;
+ switch(error_action)
+ {
+ case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
+ break;
+ case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+ break;
+ case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+ }
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ png_ptr->transformations |= PNG_EXPAND;
+#else
+ {
+ png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
+ png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
+ }
+#endif
+ {
+ png_uint_16 red_int, green_int;
+ if(red < 0 || green < 0)
+ {
+ red_int = 6968; /* .212671 * 32768 + .5 */
+ green_int = 23434; /* .715160 * 32768 + .5 */
+ }
+ else if(red + green < 100000L)
+ {
+ red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
+ green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
+ }
+ else
+ {
+ png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
+ red_int = 6968;
+ green_int = 23434;
+ }
+ png_ptr->rgb_to_gray_red_coeff = red_int;
+ png_ptr->rgb_to_gray_green_coeff = green_int;
+ png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
+ }
+}
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+ read_user_transform_fn)
+{
+ png_debug(1, "in png_set_read_user_transform_fn\n");
+ if(png_ptr == NULL) return;
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+#ifdef PNG_LEGACY_SUPPORTED
+ if(read_user_transform_fn)
+ png_warning(png_ptr,
+ "This version of libpng does not support user transforms");
+#endif
+}
+#endif
+
+/* Initialize everything needed for the read. This includes modifying
+ * the palette.
+ */
+void /* PRIVATE */
+png_init_read_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_init_read_transformations\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if(png_ptr != NULL)
+#endif
+ {
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
+ || defined(PNG_READ_GAMMA_SUPPORTED)
+ int color_type = png_ptr->color_type;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ /* Detect gray background and attempt to enable optimization
+ * for gray --> RGB case */
+ /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
+ * RGB_ALPHA (in which case need_expand is superfluous anyway), the
+ * background color might actually be gray yet not be flagged as such.
+ * This is not a problem for the current code, which uses
+ * PNG_BACKGROUND_IS_GRAY only to decide when to do the
+ * png_do_gray_to_rgb() transformation.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ !(color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ png_ptr->background.red == png_ptr->background.green &&
+ png_ptr->background.red == png_ptr->background.blue)
+ {
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ png_ptr->background.gray = png_ptr->background.red;
+ }
+#endif
+
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND))
+ {
+ if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
+ {
+ /* expand background and tRNS chunks */
+ switch (png_ptr->bit_depth)
+ {
+ case 1:
+ png_ptr->background.gray *= (png_uint_16)0xff;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_values.gray *= (png_uint_16)0xff;
+ png_ptr->trans_values.red = png_ptr->trans_values.green
+ = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ }
+ break;
+ case 2:
+ png_ptr->background.gray *= (png_uint_16)0x55;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_values.gray *= (png_uint_16)0x55;
+ png_ptr->trans_values.red = png_ptr->trans_values.green
+ = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ }
+ break;
+ case 4:
+ png_ptr->background.gray *= (png_uint_16)0x11;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_values.gray *= (png_uint_16)0x11;
+ png_ptr->trans_values.red = png_ptr->trans_values.green
+ = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ }
+ break;
+ case 8:
+ case 16:
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ break;
+ }
+ }
+ else if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_ptr->background.red =
+ png_ptr->palette[png_ptr->background.index].red;
+ png_ptr->background.green =
+ png_ptr->palette[png_ptr->background.index].green;
+ png_ptr->background.blue =
+ png_ptr->palette[png_ptr->background.index].blue;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ {
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+#endif
+ {
+ /* invert the alpha channel (in tRNS) unless the pixels are
+ going to be expanded, in which case leave it for later */
+ int i,istop;
+ istop=(int)png_ptr->num_trans;
+ for (i=0; i<istop; i++)
+ png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
+ }
+ }
+#endif
+
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+ png_ptr->background_1 = png_ptr->background;
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+
+ if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
+ && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
+ < PNG_GAMMA_THRESHOLD))
+ {
+ int i,k;
+ k=0;
+ for (i=0; i<png_ptr->num_trans; i++)
+ {
+ if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
+ k=1; /* partial transparency is present */
+ }
+ if (k == 0)
+ png_ptr->transformations &= (~PNG_GAMMA);
+ }
+
+ if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
+ png_ptr->gamma != 0.0)
+ {
+ png_build_gamma_table(png_ptr);
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ /* could skip if no transparency and
+ */
+ png_color back, back_1;
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ double g, gs;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = 1.0;
+ break;
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = 1.0 / (png_ptr->gamma);
+ gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ break;
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = 1.0 / (png_ptr->background_gamma);
+ gs = 1.0 / (png_ptr->background_gamma *
+ png_ptr->screen_gamma);
+ break;
+ default:
+ g = 1.0; /* back_1 */
+ gs = 1.0; /* back */
+ }
+
+ if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
+ {
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+ }
+ else
+ {
+ back.red = (png_byte)(pow(
+ (double)png_ptr->background.red/255, gs) * 255.0 + .5);
+ back.green = (png_byte)(pow(
+ (double)png_ptr->background.green/255, gs) * 255.0 + .5);
+ back.blue = (png_byte)(pow(
+ (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
+ }
+
+ back_1.red = (png_byte)(pow(
+ (double)png_ptr->background.red/255, g) * 255.0 + .5);
+ back_1.green = (png_byte)(pow(
+ (double)png_ptr->background.green/255, g) * 255.0 + .5);
+ back_1.blue = (png_byte)(pow(
+ (double)png_ptr->background.blue/255, g) * 255.0 + .5);
+ }
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else /* if (png_ptr->trans[i] != 0xff) */
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[palette[i].red];
+ png_composite(w, v, png_ptr->trans[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].green];
+ png_composite(w, v, png_ptr->trans[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].blue];
+ png_composite(w, v, png_ptr->trans[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+ else
+ /* color_type != PNG_COLOR_TYPE_PALETTE */
+ {
+ double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
+ double g = 1.0;
+ double gs = 1.0;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = 1.0;
+ break;
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = 1.0 / (png_ptr->gamma);
+ gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ break;
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = 1.0 / (png_ptr->background_gamma);
+ gs = 1.0 / (png_ptr->background_gamma *
+ png_ptr->screen_gamma);
+ break;
+ }
+
+ png_ptr->background_1.gray = (png_uint_16)(pow(
+ (double)png_ptr->background.gray / m, g) * m + .5);
+ png_ptr->background.gray = (png_uint_16)(pow(
+ (double)png_ptr->background.gray / m, gs) * m + .5);
+
+ if ((png_ptr->background.red != png_ptr->background.green) ||
+ (png_ptr->background.red != png_ptr->background.blue) ||
+ (png_ptr->background.red != png_ptr->background.gray))
+ {
+ /* RGB or RGBA with color background */
+ png_ptr->background_1.red = (png_uint_16)(pow(
+ (double)png_ptr->background.red / m, g) * m + .5);
+ png_ptr->background_1.green = (png_uint_16)(pow(
+ (double)png_ptr->background.green / m, g) * m + .5);
+ png_ptr->background_1.blue = (png_uint_16)(pow(
+ (double)png_ptr->background.blue / m, g) * m + .5);
+ png_ptr->background.red = (png_uint_16)(pow(
+ (double)png_ptr->background.red / m, gs) * m + .5);
+ png_ptr->background.green = (png_uint_16)(pow(
+ (double)png_ptr->background.green / m, gs) * m + .5);
+ png_ptr->background.blue = (png_uint_16)(pow(
+ (double)png_ptr->background.blue / m, gs) * m + .5);
+ }
+ else
+ {
+ /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+ png_ptr->background_1.red = png_ptr->background_1.green
+ = png_ptr->background_1.blue = png_ptr->background_1.gray;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ }
+ }
+ }
+ else
+ /* transformation does not include PNG_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ else
+#endif
+#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* No GAMMA transformation */
+ if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ (color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = (int)png_ptr->num_trans;
+ png_color back;
+ png_colorp palette = png_ptr->palette;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < istop; i++)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else if (png_ptr->trans[i] != 0xff)
+ {
+ /* The png_composite() macro is defined in png.h */
+ png_composite(palette[i].red, palette[i].red,
+ png_ptr->trans[i], back.red);
+ png_composite(palette[i].green, palette[i].green,
+ png_ptr->trans[i], back.green);
+ png_composite(palette[i].blue, palette[i].blue,
+ png_ptr->trans[i], back.blue);
+ }
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+ if ((png_ptr->transformations & PNG_SHIFT) &&
+ (color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ png_uint_16 i;
+ png_uint_16 istop = png_ptr->num_palette;
+ int sr = 8 - png_ptr->sig_bit.red;
+ int sg = 8 - png_ptr->sig_bit.green;
+ int sb = 8 - png_ptr->sig_bit.blue;
+
+ if (sr < 0 || sr > 8)
+ sr = 0;
+ if (sg < 0 || sg > 8)
+ sg = 0;
+ if (sb < 0 || sb > 8)
+ sb = 0;
+ for (i = 0; i < istop; i++)
+ {
+ png_ptr->palette[i].red >>= sr;
+ png_ptr->palette[i].green >>= sg;
+ png_ptr->palette[i].blue >>= sb;
+ }
+ }
+#endif /* PNG_READ_SHIFT_SUPPORTED */
+ }
+#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
+ && !defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if(png_ptr)
+ return;
+#endif
+}
+
+/* Modify the info structure to reflect the transformations. The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_transform_info\n");
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS))
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ else
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ else
+ {
+ if (png_ptr->num_trans)
+ {
+ if (png_ptr->transformations & PNG_EXPAND_tRNS)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ else
+ info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+ }
+ if (info_ptr->bit_depth < 8)
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ info_ptr->num_trans = 0;
+ info_ptr->background = png_ptr->background;
+ }
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (png_ptr->transformations & PNG_GAMMA)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->gamma = png_ptr->gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = png_ptr->int_gamma;
+#endif
+ }
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
+ info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ if (png_ptr->transformations & PNG_DITHER)
+ {
+ if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+ png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+ {
+ info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
+ info_ptr->bit_depth = 8;
+#endif
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+ else
+ info_ptr->channels = 1;
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
+ info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+#endif
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
+ if ((png_ptr->transformations & PNG_FILLER) &&
+ ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+ {
+ info_ptr->channels++;
+ /* if adding a true alpha channel not just filler */
+#if !defined(PNG_1_0_X)
+ if (png_ptr->transformations & PNG_ADD_ALPHA)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+#endif
+ }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if(png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if(info_ptr->bit_depth < png_ptr->user_transform_depth)
+ info_ptr->bit_depth = png_ptr->user_transform_depth;
+ if(info_ptr->channels < png_ptr->user_transform_channels)
+ info_ptr->channels = png_ptr->user_transform_channels;
+ }
+#endif
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+ info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
+
+#if !defined(PNG_READ_EXPAND_SUPPORTED)
+ if(png_ptr)
+ return;
+#endif
+}
+
+/* Transform the row. The order of transformations is significant,
+ * and is very touchy. If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_do_read_transformations\n");
+ if (png_ptr->row_buf == NULL)
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[50];
+
+ png_snprintf2(msg, 50,
+ "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
+ png_ptr->pass);
+ png_error(png_ptr, msg);
+#else
+ png_error(png_ptr, "NULL row buffer");
+#endif
+ }
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ /* Application has failed to call either png_read_start_image()
+ * or png_read_update_info() after setting transforms that expand
+ * pixels. This check added to libpng-1.2.19 */
+#if (PNG_WARN_UNINITIALIZED_ROW==1)
+ png_error(png_ptr, "Uninitialized row");
+#else
+ png_warning(png_ptr, "Uninitialized row");
+#endif
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
+ }
+ else
+ {
+ if (png_ptr->num_trans &&
+ (png_ptr->transformations & PNG_EXPAND_tRNS))
+ png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->trans_values));
+ else
+ png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ NULL);
+ }
+ }
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
+ png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ {
+ int rgb_error =
+ png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
+ if(rgb_error)
+ {
+ png_ptr->rgb_to_gray_status=1;
+ if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_WARN)
+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_ERR)
+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ }
+ }
+#endif
+
+/*
+From Andreas Dilger e-mail to png-implement, 26 March 1998:
+
+ In most cases, the "simple transparency" should be done prior to doing
+ gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ pixel is transparent. You would also need to make sure that the
+ transparency information is upgraded to RGB.
+
+ To summarize, the current flow is:
+ - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ with background "in place" if transparent,
+ convert to RGB if necessary
+ - Gray + alpha -> composite with gray background and remove alpha bytes,
+ convert to RGB if necessary
+
+ To support RGB backgrounds for gray images we need:
+ - Gray + simple transparency -> convert to RGB + simple transparency, compare
+ 3 or 6 bytes and composite with background
+ "in place" if transparent (3x compare/pixel
+ compared to doing composite with gray bkgrnd)
+ - Gray + alpha -> convert to RGB + alpha, composite with background and
+ remove alpha bytes (3x float operations/pixel
+ compared with composite on gray background)
+
+ Greg's change will do this. The reason it wasn't done before is for
+ performance, as this increases the per-pixel operations. If we would check
+ in advance if the background was gray or RGB, and position the gray-to-RGB
+ transform appropriately, then it would save a lot of work/time.
+ */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ /* if gray -> RGB, do so now only if background is non-gray; else do later
+ * for performance reasons */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ ((png_ptr->num_trans != 0 ) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
+ png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->trans_values), &(png_ptr->background)
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ , &(png_ptr->background_1),
+ png_ptr->gamma_table, png_ptr->gamma_from_1,
+ png_ptr->gamma_to_1, png_ptr->gamma_16_table,
+ png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
+ png_ptr->gamma_shift
+#endif
+);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if ((png_ptr->transformations & PNG_GAMMA) &&
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ !((png_ptr->transformations & PNG_BACKGROUND) &&
+ ((png_ptr->num_trans != 0) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+ png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->gamma_table, png_ptr->gamma_16_table,
+ png_ptr->gamma_shift);
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ if (png_ptr->transformations & PNG_16_TO_8)
+ png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ if (png_ptr->transformations & PNG_DITHER)
+ {
+ png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->palette_lookup, png_ptr->dither_index);
+ if(png_ptr->row_info.rowbytes == (png_uint_32)0)
+ png_error(png_ptr, "png_do_dither returned rowbytes=0");
+ }
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ /* if gray -> RGB, do so now only if we did not do so above */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if(png_ptr->read_user_transform_fn != NULL)
+ (*(png_ptr->read_user_transform_fn)) /* user read transform function */
+ (png_ptr, /* png_ptr */
+ &(png_ptr->row_info), /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_uint_32 rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if(png_ptr->user_transform_depth)
+ png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+ if(png_ptr->user_transform_channels)
+ png_ptr->row_info.channels = png_ptr->user_transform_channels;
+#endif
+ png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+ png_ptr->row_info.channels);
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+ }
+#endif
+
+}
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values. Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1. If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void /* PRIVATE */
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_unpack\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
+#else
+ if (row_info->bit_depth < 8)
+#endif
+ {
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x01);
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+ case 2:
+ {
+
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x03);
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x0f);
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_width * row_info->channels;
+ }
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+/* Reverse the effects of png_do_shift. This routine merely shifts the
+ * pixels back to their significant bits values. Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void /* PRIVATE */
+png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
+{
+ png_debug(1, "in png_do_unshift\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL && sig_bits != NULL &&
+#endif
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift[4];
+ int channels = 0;
+ int c;
+ png_uint_16 value = 0;
+ png_uint_32 row_width = row_info->width;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->red;
+ shift[channels++] = row_info->bit_depth - sig_bits->green;
+ shift[channels++] = row_info->bit_depth - sig_bits->blue;
+ }
+ else
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->gray;
+ }
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->alpha;
+ }
+
+ for (c = 0; c < channels; c++)
+ {
+ if (shift[c] <= 0)
+ shift[c] = 0;
+ else
+ value = 1;
+ }
+
+ if (!value)
+ return;
+
+ switch (row_info->bit_depth)
+ {
+ case 2:
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ *bp >>= 1;
+ *bp++ &= 0x55;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
+ (png_byte)((int)0xf >> shift[0]));
+
+ for (i = 0; i < istop; i++)
+ {
+ *bp >>= shift[0];
+ *bp++ &= mask;
+ }
+ break;
+ }
+ case 8:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_width * channels;
+
+ for (i = 0; i < istop; i++)
+ {
+ *bp++ >>= shift[i%channels];
+ }
+ break;
+ }
+ case 16:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_width;
+
+ for (i = 0; i < istop; i++)
+ {
+ value = (png_uint_16)((*bp << 8) + *(bp + 1));
+ value >>= shift[i%channels];
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* chop rows of bit depth 16 down to 8 */
+void /* PRIVATE */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_chop\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
+#else
+ if (row_info->bit_depth == 16)
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->width * row_info->channels;
+
+ for (i = 0; i<istop; i++, sp += 2, dp++)
+ {
+#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
+ /* This does a more accurate scaling of the 16-bit color
+ * value, rather than a simple low-byte truncation.
+ *
+ * What the ideal calculation should be:
+ * *dp = (((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
+ *
+ * GRR: no, I think this is what it really should be:
+ * *dp = (((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
+ *
+ * GRR: here's the exact calculation with shifts:
+ * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
+ * *dp = (temp - (temp >> 8)) >> 8;
+ *
+ * Approximate calculation with shift/add instead of multiply/divide:
+ * *dp = ((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
+ *
+ * What we actually do to avoid extra shifting and conversion:
+ */
+
+ *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
+#else
+ /* Simply discard the low order byte */
+ *dp = *sp;
+#endif
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from RGBA to ARGB */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+ /* This converts from RRGGBBAA to AARRGGBB */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from GA to AG */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+ /* This converts from GGAA to AAGG */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This inverts the alpha channel in RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=3;
+ dp=sp;
+ }
+ }
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=6;
+ dp=sp;
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This inverts the alpha channel in GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = *(--sp);
+ }
+ }
+ /* This inverts the alpha channel in GGAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+/*
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+*/
+ sp-=2;
+ dp=sp;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+/* Add filler channel if we have RGB color */
+void /* PRIVATE */
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+ png_uint_32 filler, png_uint_32 flags)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+ png_byte lo_filler = (png_byte)(filler & 0xff);
+
+ png_debug(1, "in png_do_read_filler\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if(row_info->bit_depth == 8)
+ {
+ /* This changes the data from G to GX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ /* This changes the data from G to XG */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ }
+ else if(row_info->bit_depth == 16)
+ {
+ /* This changes the data from GG to GGXX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ /* This changes the data from GG to XXGG */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+ } /* COLOR_TYPE == GRAY */
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if(row_info->bit_depth == 8)
+ {
+ /* This changes the data from RGB to RGBX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ /* This changes the data from RGB to XRGB */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+ else if(row_info->bit_depth == 16)
+ {
+ /* This changes the data from RRGGBB to RRGGBBXX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ /* This changes the data from RRGGBB to XXRRGGBB */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ }
+ } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* expand grayscale files to RGB, with or without alpha */
+void /* PRIVATE */
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_gray_to_rgb\n");
+ if (row_info->bit_depth >= 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + (png_size_t)row_width - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ row_info->channels += (png_byte)2;
+ row_info->color_type |= PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+ }
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ at
+ * <http://www.inforamp.net/~poynton/>
+ * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
+ *
+ * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ * We approximate this with
+ *
+ * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ * The calculation is to be done in a linear colorspace.
+ *
+ * Other integer coefficents can be used via png_set_rgb_to_gray().
+ */
+int /* PRIVATE */
+png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+ png_uint_32 i;
+
+ png_uint_32 row_width = row_info->width;
+ int rgb_error = 0;
+
+ png_debug(1, "in png_do_rgb_to_gray\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+ png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+ png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = png_ptr->gamma_to_1[*(sp++)];
+ png_byte green = png_ptr->gamma_to_1[*(sp++)];
+ png_byte blue = png_ptr->gamma_to_1[*(sp++)];
+ if(red != green || red != blue)
+ {
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1[
+ (rc*red+gc*green+bc*blue)>>15];
+ }
+ else
+ *(dp++) = *(sp-1);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+ if(red != green || red != blue)
+ {
+ rgb_error |= 1;
+ *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
+ }
+ else
+ *(dp++) = *(sp-1);
+ }
+ }
+ }
+
+ else /* RGB bit_depth == 16 */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_to_1 != NULL &&
+ png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if(red == green && red == blue)
+ w = red;
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
+ png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
+ png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ + bc*blue_1)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+ }
+ }
+ }
+ }
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = png_ptr->gamma_to_1[*(sp++)];
+ png_byte green = png_ptr->gamma_to_1[*(sp++)];
+ png_byte blue = png_ptr->gamma_to_1[*(sp++)];
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1
+ [(rc*red + gc*green + bc*blue)>>15];
+ *(dp++) = *(sp++); /* alpha */
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = *(sp++); /* alpha */
+ }
+ }
+ }
+ else /* RGBA bit_depth == 16 */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_to_1 != NULL &&
+ png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if(red == green && red == blue)
+ w = red;
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
+ png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
+ png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc * red_1
+ + gc * green_1 + bc * blue_1)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+ *(dp++) = *(sp++); /* alpha */
+ *(dp++) = *(sp++);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+ red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+ *(dp++) = *(sp++); /* alpha */
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ }
+ row_info->channels -= (png_byte)2;
+ row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+ }
+ return rgb_error;
+}
+#endif
+
+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
+ * large of png_color. This lets grayscale images be treated as
+ * paletted. Most useful for gamma correction and simplification
+ * of code.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+ int num_palette;
+ int color_inc;
+ int i;
+ int v;
+
+ png_debug(1, "in png_do_build_grayscale_palette\n");
+ if (palette == NULL)
+ return;
+
+ switch (bit_depth)
+ {
+ case 1:
+ num_palette = 2;
+ color_inc = 0xff;
+ break;
+ case 2:
+ num_palette = 4;
+ color_inc = 0x55;
+ break;
+ case 4:
+ num_palette = 16;
+ color_inc = 0x11;
+ break;
+ case 8:
+ num_palette = 256;
+ color_inc = 1;
+ break;
+ default:
+ num_palette = 0;
+ color_inc = 0;
+ break;
+ }
+
+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+ {
+ palette[i].red = (png_byte)v;
+ palette[i].green = (png_byte)v;
+ palette[i].blue = (png_byte)v;
+ }
+}
+
+/* This function is currently unused. Do we really need it? */
+#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
+void /* PRIVATE */
+png_correct_palette(png_structp png_ptr, png_colorp palette,
+ int num_palette)
+{
+ png_debug(1, "in png_correct_palette\n");
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+ if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
+ {
+ png_color back, back_1;
+
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ double g;
+
+ g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
+
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
+ fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
+ {
+ back.red = png_ptr->background.red;
+ back.green = png_ptr->background.green;
+ back.blue = png_ptr->background.blue;
+ }
+ else
+ {
+ back.red =
+ (png_byte)(pow((double)png_ptr->background.red/255, g) *
+ 255.0 + 0.5);
+ back.green =
+ (png_byte)(pow((double)png_ptr->background.green/255, g) *
+ 255.0 + 0.5);
+ back.blue =
+ (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+ 255.0 + 0.5);
+ }
+
+ g = 1.0 / png_ptr->background_gamma;
+
+ back_1.red =
+ (png_byte)(pow((double)png_ptr->background.red/255, g) *
+ 255.0 + 0.5);
+ back_1.green =
+ (png_byte)(pow((double)png_ptr->background.green/255, g) *
+ 255.0 + 0.5);
+ back_1.blue =
+ (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+ 255.0 + 0.5);
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_uint_32 i;
+
+ for (i = 0; i < (png_uint_32)num_palette; i++)
+ {
+ if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
+ png_composite(w, v, png_ptr->trans[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
+ png_composite(w, v, png_ptr->trans[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
+ png_composite(w, v, png_ptr->trans[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
+ {
+ palette[i] = back;
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ }
+ else
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (png_ptr->transformations & PNG_GAMMA)
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ else
+#endif
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_color back;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < (int)png_ptr->num_trans; i++)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i].red = back.red;
+ palette[i].green = back.green;
+ palette[i].blue = back.blue;
+ }
+ else if (png_ptr->trans[i] != 0xff)
+ {
+ png_composite(palette[i].red, png_ptr->palette[i].red,
+ png_ptr->trans[i], back.red);
+ png_composite(palette[i].green, png_ptr->palette[i].green,
+ png_ptr->trans[i], back.green);
+ png_composite(palette[i].blue, png_ptr->palette[i].blue,
+ png_ptr->trans[i], back.blue);
+ }
+ }
+ }
+ else /* assume grayscale palette (what else could it be?) */
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i == (png_byte)png_ptr->trans_values.gray)
+ {
+ palette[i].red = (png_byte)png_ptr->background.red;
+ palette[i].green = (png_byte)png_ptr->background.green;
+ palette[i].blue = (png_byte)png_ptr->background.blue;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0. Paletted files have already been taken care of.
+ */
+void /* PRIVATE */
+png_do_background(png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ , png_color_16p background_1,
+ png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+ png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+ png_uint_16pp gamma_16_to_1, int gamma_shift
+#endif
+ )
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+ int shift;
+
+ png_debug(1, "in png_do_background\n");
+ if (background != NULL &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
+ (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row;
+ shift = 7;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x01)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 7;
+ sp++;
+ }
+ else
+ shift--;
+ }
+ break;
+ }
+ case 2:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ else
+ {
+ png_byte p = (png_byte)((*sp >> shift) & 0x03);
+ png_byte g = (png_byte)((gamma_table [p | (p << 2) |
+ (p << 4) | (p << 6)] >> 6) & 0x03);
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(g << shift);
+ }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+ else
+ shift -= 2;
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+ else
+ shift -= 2;
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ else
+ {
+ png_byte p = (png_byte)((*sp >> shift) & 0x0f);
+ png_byte g = (png_byte)((gamma_table[p |
+ (p << 4)] >> 4) & 0x0f);
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(g << shift);
+ }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+ else
+ shift -= 4;
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+ else
+ shift -= 4;
+ }
+ }
+ break;
+ }
+ case 8:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == trans_values->gray)
+ {
+ *sp = (png_byte)background->gray;
+ }
+ else
+ {
+ *sp = gamma_table[*sp];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == trans_values->gray)
+ {
+ *sp = (png_byte)background->gray;
+ }
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (v == trans_values->gray)
+ {
+ /* background is already in screen gamma */
+ *sp = (png_byte)((background->gray >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->gray & 0xff);
+ }
+ else
+ {
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (v == trans_values->gray)
+ {
+ *sp = (png_byte)((background->gray >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->gray & 0xff);
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == trans_values->red &&
+ *(sp + 1) == trans_values->green &&
+ *(sp + 2) == trans_values->blue)
+ {
+ *sp = (png_byte)background->red;
+ *(sp + 1) = (png_byte)background->green;
+ *(sp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == trans_values->red &&
+ *(sp + 1) == trans_values->green &&
+ *(sp + 2) == trans_values->blue)
+ {
+ *sp = (png_byte)background->red;
+ *(sp + 1) = (png_byte)background->green;
+ *(sp + 2) = (png_byte)background->blue;
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+ if (r == trans_values->red && g == trans_values->green &&
+ b == trans_values->blue)
+ {
+ /* background is already in screen gamma */
+ *sp = (png_byte)((background->red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->red & 0xff);
+ *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(background->green & 0xff);
+ *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
+ png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+
+ if (r == trans_values->red && g == trans_values->green &&
+ b == trans_values->blue)
+ {
+ *sp = (png_byte)((background->red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->red & 0xff);
+ *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(background->green & 0xff);
+ *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 2, dp++)
+ {
+ png_uint_16 a = *(sp + 1);
+
+ if (a == 0xff)
+ {
+ *dp = gamma_table[*sp];
+ }
+ else if (a == 0)
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)background->gray;
+ }
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, background_1->gray);
+ *dp = gamma_from_1[w];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 2, dp++)
+ {
+ png_byte a = *(sp + 1);
+
+ if (a == 0xff)
+ {
+ *dp = *sp;
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else if (a == 0)
+ {
+ *dp = (png_byte)background->gray;
+ }
+ else
+ {
+ png_composite(*dp, *sp, a, background_1->gray);
+ }
+#else
+ *dp = (png_byte)background->gray;
+#endif
+ }
+ }
+ }
+ else /* if (png_ptr->bit_depth == 16) */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else if (a == 0)
+#else
+ else
+#endif
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)((background->gray >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->gray & 0xff);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else
+ {
+ png_uint_16 g, v, w;
+
+ g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(v, g, a, background_1->gray);
+ w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+ *dp = (png_byte)((w >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(w & 0xff);
+ }
+#endif
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_memcpy(dp, sp, 2);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else if (a == 0)
+#else
+ else
+#endif
+ {
+ *dp = (png_byte)((background->gray >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->gray & 0xff);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else
+ {
+ png_uint_16 g, v;
+
+ g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_composite_16(v, g, a, background_1->gray);
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ }
+#endif
+ }
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *dp = gamma_table[*sp];
+ *(dp + 1) = gamma_table[*(sp + 1)];
+ *(dp + 2) = gamma_table[*(sp + 2)];
+ }
+ else if (a == 0)
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)background->red;
+ *(dp + 1) = (png_byte)background->green;
+ *(dp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, background_1->red);
+ *dp = gamma_from_1[w];
+ v = gamma_to_1[*(sp + 1)];
+ png_composite(w, v, a, background_1->green);
+ *(dp + 1) = gamma_from_1[w];
+ v = gamma_to_1[*(sp + 2)];
+ png_composite(w, v, a, background_1->blue);
+ *(dp + 2) = gamma_from_1[w];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *dp = *sp;
+ *(dp + 1) = *(sp + 1);
+ *(dp + 2) = *(sp + 2);
+ }
+ else if (a == 0)
+ {
+ *dp = (png_byte)background->red;
+ *(dp + 1) = (png_byte)background->green;
+ *(dp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ png_composite(*dp, *sp, a, background->red);
+ png_composite(*(dp + 1), *(sp + 1), a,
+ background->green);
+ png_composite(*(dp + 2), *(sp + 2), a,
+ background->blue);
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(v & 0xff);
+ }
+ else if (a == 0)
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)((background->red >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->red & 0xff);
+ *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(background->green & 0xff);
+ *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v, w, x;
+
+ v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(w, v, a, background_1->red);
+ x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+ *dp = (png_byte)((x >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(x & 0xff);
+ v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ png_composite_16(w, v, a, background_1->green);
+ x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+ *(dp + 2) = (png_byte)((x >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(x & 0xff);
+ v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ png_composite_16(w, v, a, background_1->blue);
+ x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
+ *(dp + 4) = (png_byte)((x >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(x & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_memcpy(dp, sp, 6);
+ }
+ else if (a == 0)
+ {
+ *dp = (png_byte)((background->red >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->red & 0xff);
+ *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(background->green & 0xff);
+ *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v;
+
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ png_composite_16(v, r, a, background->red);
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ png_composite_16(v, g, a, background->green);
+ *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(v & 0xff);
+ png_composite_16(v, b, a, background->blue);
+ *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ row_info->channels--;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Gamma correct the image, avoiding the alpha channel. Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift. Build these with
+ * build_gamma_table().
+ */
+void /* PRIVATE */
+png_do_gamma(png_row_infop row_info, png_bytep row,
+ png_bytep gamma_table, png_uint_16pp gamma_16_table,
+ int gamma_shift)
+{
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_gamma\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+ (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ sp++;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp += 2;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ if (row_info->bit_depth == 2)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 4)
+ {
+ int a = *sp & 0xc0;
+ int b = *sp & 0x30;
+ int c = *sp & 0x0c;
+ int d = *sp & 0x03;
+
+ *sp = (png_byte)(
+ ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
+ ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+ ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+ ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+ sp++;
+ }
+ }
+ if (row_info->bit_depth == 4)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 2)
+ {
+ int msb = *sp & 0xf0;
+ int lsb = *sp & 0x0f;
+
+ *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+ | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+ sp++;
+ }
+ }
+ else if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+ png_colorp palette, png_bytep trans, int num_trans)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand_palette\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 1;
+ else
+ *dp = 0;
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+ case 2:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)value;
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+ case 4:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((row_width & 0x01) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)value;
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+ switch (row_info->bit_depth)
+ {
+ case 8:
+ {
+ if (trans != NULL)
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if ((int)(*sp) >= num_trans)
+ *dp-- = 0xff;
+ else
+ *dp-- = trans[*sp];
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ row_info->color_type = 6;
+ row_info->channels = 4;
+ }
+ else
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width * 3) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ row_info->color_type = 2;
+ row_info->channels = 3;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* If the bit depth < 8, it is expanded to 8. Also, if the already
+ * expanded transparency value is supplied, an alpha channel is built.
+ */
+void /* PRIVATE */
+png_do_expand(png_row_infop row_info, png_bytep row,
+ png_color_16p trans_value)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
+
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ gray = (png_uint_16)((gray&0x01)*0xff);
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 0xff;
+ else
+ *dp = 0;
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+ case 2:
+ {
+ gray = (png_uint_16)((gray&0x03)*0x55);
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)(value | (value << 2) | (value << 4) |
+ (value << 6));
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+ case 4:
+ {
+ gray = (png_uint_16)((gray&0x0f)*0x11);
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)(value | (value << 4));
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (trans_value != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ gray = gray & 0xff;
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp == gray)
+ *dp-- = 0;
+ else
+ *dp-- = 0xff;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_byte gray_high = (gray >> 8) & 0xff;
+ png_byte gray_low = gray & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (row_info->rowbytes << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp-1) == gray_high && *(sp) == gray_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ row_info->channels = 2;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_width);
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_byte red = trans_value->red & 0xff;
+ png_byte green = trans_value->green & 0xff;
+ png_byte blue = trans_value->blue & 0xff;
+ sp = row + (png_size_t)row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+ *dp-- = 0;
+ else
+ *dp-- = 0xff;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_byte red_high = (trans_value->red > 8) & 0xff;
+ png_byte green_high = (trans_value->green > 8) & 0xff;
+ png_byte blue_high = (trans_value->blue > 8) & 0xff;
+ png_byte red_low = trans_value->red & 0xff;
+ png_byte green_low = trans_value->green & 0xff;
+ png_byte blue_low = trans_value->blue & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 3) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 5) == red_high &&
+ *(sp - 4) == red_low &&
+ *(sp - 3) == green_high &&
+ *(sp - 2) == green_low &&
+ *(sp - 1) == blue_high &&
+ *(sp ) == blue_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ row_info->channels = 4;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+void /* PRIVATE */
+png_do_dither(png_row_infop row_info, png_bytep row,
+ png_bytep palette_lookup, png_bytep dither_lookup)
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_dither\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+ palette_lookup && row_info->bit_depth == 8)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+
+ /* this looks real messy, but the compiler will reduce
+ it down to a reasonable formula. For example, with
+ 5 bits per color, we get:
+ p = (((r >> 3) & 0x1f) << 10) |
+ (((g >> 3) & 0x1f) << 5) |
+ ((b >> 3) & 0x1f);
+ */
+ p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+ ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+ (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+ (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+ ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+ (PNG_DITHER_BLUE_BITS)) |
+ ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+ ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ palette_lookup != NULL && row_info->bit_depth == 8)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+ sp++;
+
+ p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+ ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+ (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+ (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+ ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+ (PNG_DITHER_BLUE_BITS)) |
+ ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+ ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ dither_lookup && row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ *sp = dither_lookup[*sp];
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+static PNG_CONST int png_gamma_shift[] =
+ {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
+
+/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future. Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void /* PRIVATE */
+png_build_gamma_table(png_structp png_ptr)
+{
+ png_debug(1, "in png_build_gamma_table\n");
+
+ if (png_ptr->bit_depth <= 8)
+ {
+ int i;
+ double g;
+
+ if (png_ptr->screen_gamma > .000001)
+ g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ else
+ g = 1.0;
+
+ png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
+ {
+
+ g = 1.0 / (png_ptr->gamma);
+
+ png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+ }
+
+
+ png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ if(png_ptr->screen_gamma > 0.000001)
+ g = 1.0 / png_ptr->screen_gamma;
+ else
+ g = png_ptr->gamma; /* probably doing rgb_to_gray */
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+ }
+ else
+ {
+ double g;
+ int i, j, shift, num;
+ int sig_bit;
+ png_uint_32 ig;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit = (int)png_ptr->sig_bit.red;
+ if ((int)png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+ if ((int)png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ {
+ sig_bit = (int)png_ptr->sig_bit.gray;
+ }
+
+ if (sig_bit > 0)
+ shift = 16 - sig_bit;
+ else
+ shift = 0;
+
+ if (png_ptr->transformations & PNG_16_TO_8)
+ {
+ if (shift < (16 - PNG_MAX_GAMMA_8))
+ shift = (16 - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8)
+ shift = 8;
+ if (shift < 0)
+ shift = 0;
+
+ png_ptr->gamma_shift = (png_byte)shift;
+
+ num = (1 << (8 - shift));
+
+ if (png_ptr->screen_gamma > .000001)
+ g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ else
+ g = 1.0;
+
+ png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
+ (png_uint_32)(num * png_sizeof (png_uint_16p)));
+
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
+ {
+ double fin, fout;
+ png_uint_32 last, max;
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof (png_uint_16)));
+ }
+
+ g = 1.0 / g;
+ last = 0;
+ for (i = 0; i < 256; i++)
+ {
+ fout = ((double)i + 0.5) / 256.0;
+ fin = pow(fout, g);
+ max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
+ while (last <= max)
+ {
+ png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+ [(int)(last >> (8 - shift))] = (png_uint_16)(
+ (png_uint_16)i | ((png_uint_16)i << 8));
+ last++;
+ }
+ }
+ while (last < ((png_uint_32)num << 8))
+ {
+ png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+ [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
+ last++;
+ }
+ }
+ else
+ {
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof (png_uint_16)));
+
+ ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_table[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
+ {
+
+ g = 1.0 / (png_ptr->gamma);
+
+ png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
+ (png_uint_32)(num * png_sizeof (png_uint_16p )));
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof (png_uint_16)));
+
+ ig = (((png_uint_32)i *
+ (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_to_1[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+
+ if(png_ptr->screen_gamma > 0.000001)
+ g = 1.0 / png_ptr->screen_gamma;
+ else
+ g = png_ptr->gamma; /* probably doing rgb_to_gray */
+
+ png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
+ (png_uint_32)(num * png_sizeof (png_uint_16p)));
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof (png_uint_16)));
+
+ ig = (((png_uint_32)i *
+ (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_from_1[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+ }
+}
+#endif
+/* To do: install integer version of png_build_gamma_table here */
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_intrapixel\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
+ *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
+ png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
+ png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
+ png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp+1) = (png_byte)(red & 0xff);
+ *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp+5) = (png_byte)(blue & 0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngrutil.c b/kernel/kls_png/ksquirrel-libs-png/pngrutil.c
new file mode 100644
index 0000000..899cdc4
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngrutil.c
@@ -0,0 +1,3392 @@
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * Last changed in libpng 1.2.19 August 19, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED)
+
+#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
+# define WIN32_WCE_OLD
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+# if defined(WIN32_WCE_OLD)
+/* strtod() function is not supported on WindowsCE */
+__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
+{
+ double result = 0;
+ int len;
+ wchar_t *str, *end;
+
+ len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
+ str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
+ if ( NULL != str )
+ {
+ MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
+ result = wcstod(str, &end);
+ len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
+ *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
+ png_free(png_ptr, str);
+ }
+ return result;
+}
+# else
+# define png_strtod(p,a,b) strtod(a,b)
+# endif
+#endif
+
+png_uint_32 PNGAPI
+png_get_uint_31(png_structp png_ptr, png_bytep buf)
+{
+ png_uint_32 i = png_get_uint_32(buf);
+ if (i > PNG_UINT_31_MAX)
+ png_error(png_ptr, "PNG unsigned integer out of range.");
+ return (i);
+}
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 PNGAPI
+png_get_uint_32(png_bytep buf)
+{
+ png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ (png_uint_32)(*(buf + 3));
+
+ return (i);
+}
+
+/* Grab a signed 32-bit integer from a buffer in big-endian format. The
+ * data is stored in the PNG file in two's complement format, and it is
+ * assumed that the machine format for signed integers is the same. */
+png_int_32 PNGAPI
+png_get_int_32(png_bytep buf)
+{
+ png_int_32 i = ((png_int_32)(*buf) << 24) +
+ ((png_int_32)(*(buf + 1)) << 16) +
+ ((png_int_32)(*(buf + 2)) << 8) +
+ (png_int_32)(*(buf + 3));
+
+ return (i);
+}
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 PNGAPI
+png_get_uint_16(png_bytep buf)
+{
+ png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
+ (png_uint_16)(*(buf + 1)));
+
+ return (i);
+}
+#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
+{
+ if(png_ptr == NULL) return;
+ png_read_data(png_ptr, buf, length);
+ png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC. Depending on whether we
+ are reading a ancillary or critical chunk, and how the program has set
+ things up, we may calculate the CRC on the data and print a message.
+ Returns '1' if there was a CRC error, '0' otherwise. */
+int /* PRIVATE */
+png_crc_finish(png_structp png_ptr, png_uint_32 skip)
+{
+ png_size_t i;
+ png_size_t istop = png_ptr->zbuf_size;
+
+ for (i = (png_size_t)skip; i > istop; i -= istop)
+ {
+ png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ }
+ if (i)
+ {
+ png_crc_read(png_ptr, png_ptr->zbuf, i);
+ }
+
+ if (png_crc_error(png_ptr))
+ {
+ if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
+ !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
+ (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ else
+ {
+ png_chunk_error(png_ptr, "CRC error");
+ }
+ return (1);
+ }
+
+ return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ the data it has read thus far. */
+int /* PRIVATE */
+png_crc_error(png_structp png_ptr)
+{
+ png_byte crc_bytes[4];
+ png_uint_32 crc;
+ int need_crc = 1;
+
+ if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ png_read_data(png_ptr, crc_bytes, 4);
+
+ if (need_crc)
+ {
+ crc = png_get_uint_32(crc_bytes);
+ return ((int)(crc != png_ptr->crc));
+ }
+ else
+ return (0);
+}
+
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+ defined(PNG_READ_iCCP_SUPPORTED)
+/*
+ * Decompress trailing data in a chunk. The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part. What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+png_charp /* PRIVATE */
+png_decompress_chunk(png_structp png_ptr, int comp_type,
+ png_charp chunkdata, png_size_t chunklength,
+ png_size_t prefix_size, png_size_t *newlength)
+{
+ static PNG_CONST char msg[] = "Error decoding compressed text";
+ png_charp text;
+ png_size_t text_size;
+
+ if (comp_type == PNG_COMPRESSION_TYPE_BASE)
+ {
+ int ret = Z_OK;
+ png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
+ png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ text_size = 0;
+ text = NULL;
+
+ while (png_ptr->zstream.avail_in)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_warning(png_ptr, png_ptr->zstream.msg);
+ else
+ png_warning(png_ptr, msg);
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ if (text == NULL)
+ {
+ text_size = prefix_size + png_sizeof(msg) + 1;
+ text = (png_charp)png_malloc_warn(png_ptr, text_size);
+ if (text == NULL)
+ {
+ png_free(png_ptr,chunkdata);
+ png_error(png_ptr,"Not enough memory to decompress chunk");
+ }
+ png_memcpy(text, chunkdata, prefix_size);
+ }
+
+ text[text_size - 1] = 0x00;
+
+ /* Copy what we can of the error message into the text chunk */
+ text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
+ text_size = png_sizeof(msg) > text_size ? text_size :
+ png_sizeof(msg);
+ png_memcpy(text + prefix_size, msg, text_size + 1);
+ break;
+ }
+ if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
+ {
+ if (text == NULL)
+ {
+ text_size = prefix_size +
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
+ if (text == NULL)
+ {
+ png_free(png_ptr,chunkdata);
+ png_error(png_ptr,"Not enough memory to decompress chunk.");
+ }
+ png_memcpy(text + prefix_size, png_ptr->zbuf,
+ text_size - prefix_size);
+ png_memcpy(text, chunkdata, prefix_size);
+ *(text + text_size) = 0x00;
+ }
+ else
+ {
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc_warn(png_ptr,
+ (png_uint_32)(text_size +
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+ if (text == NULL)
+ {
+ png_free(png_ptr, tmp);
+ png_free(png_ptr, chunkdata);
+ png_error(png_ptr,"Not enough memory to decompress chunk..");
+ }
+ png_memcpy(text, tmp, text_size);
+ png_free(png_ptr, tmp);
+ png_memcpy(text + text_size, png_ptr->zbuf,
+ (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+ text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ *(text + text_size) = 0x00;
+ }
+ if (ret == Z_STREAM_END)
+ break;
+ else
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ }
+ if (ret != Z_STREAM_END)
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char umsg[52];
+
+ if (ret == Z_BUF_ERROR)
+ png_snprintf(umsg, 52,
+ "Buffer error in compressed datastream in %s chunk",
+ png_ptr->chunk_name);
+ else if (ret == Z_DATA_ERROR)
+ png_snprintf(umsg, 52,
+ "Data error in compressed datastream in %s chunk",
+ png_ptr->chunk_name);
+ else
+ png_snprintf(umsg, 52,
+ "Incomplete compressed datastream in %s chunk",
+ png_ptr->chunk_name);
+ png_warning(png_ptr, umsg);
+#else
+ png_warning(png_ptr,
+ "Incomplete compressed datastream in chunk other than IDAT");
+#endif
+ text_size=prefix_size;
+ if (text == NULL)
+ {
+ text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
+ if (text == NULL)
+ {
+ png_free(png_ptr, chunkdata);
+ png_error(png_ptr,"Not enough memory for text.");
+ }
+ png_memcpy(text, chunkdata, prefix_size);
+ }
+ *(text + text_size) = 0x00;
+ }
+
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ png_free(png_ptr, chunkdata);
+ chunkdata = text;
+ *newlength=text_size;
+ }
+ else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char umsg[50];
+
+ png_snprintf(umsg, 50,
+ "Unknown zTXt compression type %d", comp_type);
+ png_warning(png_ptr, umsg);
+#else
+ png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+ *(chunkdata + prefix_size) = 0x00;
+ *newlength=prefix_size;
+ }
+
+ return chunkdata;
+}
+#endif
+
+/* read and check the IDHR chunk */
+void /* PRIVATE */
+png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[13];
+ png_uint_32 width, height;
+ int bit_depth, color_type, compression_type, filter_type;
+ int interlace_type;
+
+ png_debug(1, "in png_handle_IHDR\n");
+
+ if (png_ptr->mode & PNG_HAVE_IHDR)
+ png_error(png_ptr, "Out of place IHDR");
+
+ /* check the length */
+ if (length != 13)
+ png_error(png_ptr, "Invalid IHDR chunk");
+
+ png_ptr->mode |= PNG_HAVE_IHDR;
+
+ png_crc_read(png_ptr, buf, 13);
+ png_crc_finish(png_ptr, 0);
+
+ width = png_get_uint_31(png_ptr, buf);
+ height = png_get_uint_31(png_ptr, buf + 4);
+ bit_depth = buf[8];
+ color_type = buf[9];
+ compression_type = buf[10];
+ filter_type = buf[11];
+ interlace_type = buf[12];
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+ png_ptr->first_frame_width = width;
+ png_ptr->first_frame_height = height;
+#endif
+
+ /* set internal variables */
+ png_ptr->width = width;
+ png_ptr->height = height;
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->interlaced = (png_byte)interlace_type;
+ png_ptr->color_type = (png_byte)color_type;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+
+ /* find number of channels */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_PALETTE:
+ png_ptr->channels = 1;
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->channels = 3;
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_ptr->channels = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_ptr->channels = 4;
+ break;
+ }
+
+ /* set up other useful info */
+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+ png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
+ png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
+ png_debug1(3,"channels = %d\n", png_ptr->channels);
+ png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
+ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+ color_type, interlace_type, compression_type, filter_type);
+}
+
+/* read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_color palette[PNG_MAX_PALETTE_LENGTH];
+ int num, i;
+#ifndef PNG_NO_POINTER_INDEXING
+ png_colorp pal_ptr;
+#endif
+
+ png_debug(1, "in png_handle_PLTE\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before PLTE");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid PLTE after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ png_error(png_ptr, "Duplicate PLTE chunk");
+
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring PLTE chunk in grayscale PNG");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+ {
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_warning(png_ptr, "Invalid palette chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else
+ {
+ png_error(png_ptr, "Invalid palette chunk");
+ }
+ }
+
+ num = (int)length / 3;
+
+#ifndef PNG_NO_POINTER_INDEXING
+ for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ pal_ptr->red = buf[0];
+ pal_ptr->green = buf[1];
+ pal_ptr->blue = buf[2];
+ }
+#else
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ /* don't depend upon png_color being any order */
+ palette[i].red = buf[0];
+ palette[i].green = buf[1];
+ palette[i].blue = buf[2];
+ }
+#endif
+
+ /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
+ whatever the normal CRC configuration tells us. However, if we
+ have an RGB image, the PLTE can be considered ancillary, so
+ we will act as though it is. */
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+ {
+ png_crc_finish(png_ptr, 0);
+ }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+ else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
+ {
+ /* If we don't want to use the data from an ancillary chunk,
+ we have two options: an error abort, or a warning and we
+ ignore the data in this chunk (which should be OK, since
+ it's considered ancillary for a RGB or RGBA image). */
+ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+ {
+ png_chunk_error(png_ptr, "CRC error");
+ }
+ else
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ return;
+ }
+ }
+ /* Otherwise, we (optionally) emit a warning and use the chunk. */
+ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ }
+#endif
+
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ if (png_ptr->num_trans > (png_uint_16)num)
+ {
+ png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
+ png_ptr->num_trans = (png_uint_16)num;
+ }
+ if (info_ptr->num_trans > (png_uint_16)num)
+ {
+ png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
+ info_ptr->num_trans = (png_uint_16)num;
+ }
+ }
+ }
+#endif
+
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_debug(1, "in png_handle_IEND\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+ {
+ png_error(png_ptr, "No image in file");
+ }
+
+ png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+ if (length != 0)
+ {
+ png_warning(png_ptr, "Incorrect IEND chunk length");
+ }
+ png_crc_finish(png_ptr, length);
+
+ info_ptr =info_ptr; /* quiet compiler warnings about unused info_ptr */
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+void /* PRIVATE */
+png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_fixed_point igamma;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float file_gamma;
+#endif
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_gAMA\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before gAMA");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid gAMA after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place gAMA chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+ )
+ {
+ png_warning(png_ptr, "Duplicate gAMA chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 4)
+ {
+ png_warning(png_ptr, "Incorrect gAMA chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ igamma = (png_fixed_point)png_get_uint_32(buf);
+ /* check for zero gamma */
+ if (igamma == 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring gAMA chunk with gamma=0");
+ return;
+ }
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+ if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+ fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
+#endif
+ return;
+ }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ file_gamma = (float)igamma / (float)100000.0;
+# ifdef PNG_READ_GAMMA_SUPPORTED
+ png_ptr->gamma = file_gamma;
+# endif
+ png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_size_t truelen;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_sBIT\n");
+
+ buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sBIT");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sBIT after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ {
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place sBIT chunk");
+ }
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+ {
+ png_warning(png_ptr, "Duplicate sBIT chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 3;
+ else
+ truelen = (png_size_t)png_ptr->channels;
+
+ if (length != truelen || length > 4)
+ {
+ png_warning(png_ptr, "Incorrect sBIT chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[1];
+ png_ptr->sig_bit.blue = buf[2];
+ png_ptr->sig_bit.alpha = buf[3];
+ }
+ else
+ {
+ png_ptr->sig_bit.gray = buf[0];
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[0];
+ png_ptr->sig_bit.blue = buf[0];
+ png_ptr->sig_bit.alpha = buf[1];
+ }
+ png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+void /* PRIVATE */
+png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[4];
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+ png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+ int_y_green, int_x_blue, int_y_blue;
+
+ png_uint_32 uint_x, uint_y;
+
+ png_debug(1, "in png_handle_cHRM\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before cHRM");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid cHRM after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Missing PLTE before cHRM");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+ )
+ {
+ png_warning(png_ptr, "Duplicate cHRM chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 32)
+ {
+ png_warning(png_ptr, "Incorrect cHRM chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x > 80000L || uint_y > 80000L ||
+ uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM white point");
+ png_crc_finish(png_ptr, 24);
+ return;
+ }
+ int_x_white = (png_fixed_point)uint_x;
+ int_y_white = (png_fixed_point)uint_y;
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM red point");
+ png_crc_finish(png_ptr, 16);
+ return;
+ }
+ int_x_red = (png_fixed_point)uint_x;
+ int_y_red = (png_fixed_point)uint_y;
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM green point");
+ png_crc_finish(png_ptr, 8);
+ return;
+ }
+ int_x_green = (png_fixed_point)uint_x;
+ int_y_green = (png_fixed_point)uint_y;
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM blue point");
+ png_crc_finish(png_ptr, 0);
+ return;
+ }
+ int_x_blue = (png_fixed_point)uint_x;
+ int_y_blue = (png_fixed_point)uint_y;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ white_x = (float)int_x_white / (float)100000.0;
+ white_y = (float)int_y_white / (float)100000.0;
+ red_x = (float)int_x_red / (float)100000.0;
+ red_y = (float)int_y_red / (float)100000.0;
+ green_x = (float)int_x_green / (float)100000.0;
+ green_y = (float)int_y_green / (float)100000.0;
+ blue_x = (float)int_x_blue / (float)100000.0;
+ blue_y = (float)int_y_blue / (float)100000.0;
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
+ {
+ if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
+ PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
+ PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
+ PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect cHRM value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
+ white_x, white_y, red_x, red_y);
+ fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
+ green_x, green_y, blue_x, blue_y);
+#else
+ fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+ int_x_white, int_y_white, int_x_red, int_y_red);
+ fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+ int_x_green, int_y_green, int_x_blue, int_y_blue);
+#endif
+#endif /* PNG_NO_CONSOLE_IO */
+ }
+ png_crc_finish(png_ptr, 0);
+ return;
+ }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_cHRM(png_ptr, info_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+ int_y_green, int_x_blue, int_y_blue);
+#endif
+ if (png_crc_finish(png_ptr, 0))
+ return;
+}
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+void /* PRIVATE */
+png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ int intent;
+ png_byte buf[1];
+
+ png_debug(1, "in png_handle_sRGB\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sRGB");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sRGB after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place sRGB chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+ {
+ png_warning(png_ptr, "Duplicate sRGB chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 1)
+ {
+ png_warning(png_ptr, "Incorrect sRGB chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 1);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ intent = buf[0];
+ /* check for bad intent */
+ if (intent >= PNG_sRGB_INTENT_LAST)
+ {
+ png_warning(png_ptr, "Unknown sRGB intent");
+ return;
+ }
+
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
+ {
+ png_fixed_point igamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ igamma=info_ptr->int_gamma;
+#else
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
+# endif
+#endif
+ if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+# ifdef PNG_FIXED_POINT_SUPPORTED
+ fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
+# else
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
+# endif
+# endif
+#endif
+ }
+ }
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect cHRM value when sRGB is also present");
+ }
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+void /* PRIVATE */
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_charp chunkdata;
+ png_byte compression_type;
+ png_bytep pC;
+ png_charp profile;
+ png_uint_32 skip = 0;
+ png_uint_32 profile_size, profile_length;
+ png_size_t slength, prefix_length, data_length;
+
+ png_debug(1, "in png_handle_iCCP\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before iCCP");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid iCCP after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place iCCP chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
+ {
+ png_warning(png_ptr, "Duplicate iCCP chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (profile = chunkdata; *profile; profile++)
+ /* empty loop to find end of name */ ;
+
+ ++profile;
+
+ /* there should be at least one zero (the compression type byte)
+ following the separator, and we should be on it */
+ if ( profile >= chunkdata + slength - 1)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Malformed iCCP chunk");
+ return;
+ }
+
+ /* compression_type should always be zero */
+ compression_type = *profile++;
+ if (compression_type)
+ {
+ png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
+ compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
+ wrote nonzero) */
+ }
+
+ prefix_length = profile - chunkdata;
+ chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
+ slength, prefix_length, &data_length);
+
+ profile_length = data_length - prefix_length;
+
+ if ( prefix_length > data_length || profile_length < 4)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Profile size field missing from iCCP chunk");
+ return;
+ }
+
+ /* Check the profile_size recorded in the first 32 bits of the ICC profile */
+ pC = (png_bytep)(chunkdata+prefix_length);
+ profile_size = ((*(pC ))<<24) |
+ ((*(pC+1))<<16) |
+ ((*(pC+2))<< 8) |
+ ((*(pC+3)) );
+
+ if(profile_size < profile_length)
+ profile_length = profile_size;
+
+ if(profile_size > profile_length)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Ignoring truncated iCCP profile.");
+ return;
+ }
+
+ png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
+ chunkdata + prefix_length, profile_length);
+ png_free(png_ptr, chunkdata);
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_bytep chunkdata;
+ png_bytep entry_start;
+ png_sPLT_t new_palette;
+#ifdef PNG_NO_POINTER_INDEXING
+ png_sPLT_entryp pp;
+#endif
+ int data_length, entry_size, i;
+ png_uint_32 skip = 0;
+ png_size_t slength;
+
+ png_debug(1, "in png_handle_sPLT\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sPLT");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sPLT after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (entry_start = chunkdata; *entry_start; entry_start++)
+ /* empty loop to find end of name */ ;
+ ++entry_start;
+
+ /* a sample depth should follow the separator, and we should be on it */
+ if (entry_start > chunkdata + slength - 2)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "malformed sPLT chunk");
+ return;
+ }
+
+ new_palette.depth = *entry_start++;
+ entry_size = (new_palette.depth == 8 ? 6 : 10);
+ data_length = (slength - (entry_start - chunkdata));
+
+ /* integrity-check the data length */
+ if (data_length % entry_size)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "sPLT chunk has bad length");
+ return;
+ }
+
+ new_palette.nentries = (png_int_32) ( data_length / entry_size);
+ if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
+ png_sizeof(png_sPLT_entry)))
+ {
+ png_warning(png_ptr, "sPLT chunk too long");
+ return;
+ }
+ new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+ png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
+ if (new_palette.entries == NULL)
+ {
+ png_warning(png_ptr, "sPLT chunk requires too much memory");
+ return;
+ }
+
+#ifndef PNG_NO_POINTER_INDEXING
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+ png_sPLT_entryp pp = new_palette.entries + i;
+
+ if (new_palette.depth == 8)
+ {
+ pp->red = *entry_start++;
+ pp->green = *entry_start++;
+ pp->blue = *entry_start++;
+ pp->alpha = *entry_start++;
+ }
+ else
+ {
+ pp->red = png_get_uint_16(entry_start); entry_start += 2;
+ pp->green = png_get_uint_16(entry_start); entry_start += 2;
+ pp->blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#else
+ pp = new_palette.entries;
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+
+ if (new_palette.depth == 8)
+ {
+ pp[i].red = *entry_start++;
+ pp[i].green = *entry_start++;
+ pp[i].blue = *entry_start++;
+ pp[i].alpha = *entry_start++;
+ }
+ else
+ {
+ pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#endif
+
+ /* discard all chunk data except the name and stash that */
+ new_palette.name = (png_charp)chunkdata;
+
+ png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+ png_free(png_ptr, chunkdata);
+ png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+void /* PRIVATE */
+png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+ int bit_mask;
+
+ png_debug(1, "in png_handle_tRNS\n");
+
+ /* For non-indexed color, mask off any bits in the tRNS value that
+ * exceed the bit depth. Some creators were writing extra bits there.
+ * This is not needed for indexed color. */
+ bit_mask = (1 << png_ptr->bit_depth) - 1;
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before tRNS");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid tRNS after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_warning(png_ptr, "Duplicate tRNS chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_byte buf[2];
+
+ if (length != 2)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 2);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_values.gray = png_get_uint_16(buf) & bit_mask;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_byte buf[6];
+
+ if (length != 6)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ png_crc_read(png_ptr, buf, (png_size_t)length);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_values.red = png_get_uint_16(buf) & bit_mask;
+ png_ptr->trans_values.green = png_get_uint_16(buf + 2) & bit_mask;
+ png_ptr->trans_values.blue = png_get_uint_16(buf + 4) & bit_mask;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ /* Should be an error, but we can cope with it. */
+ png_warning(png_ptr, "Missing PLTE before tRNS");
+ }
+ if (length > (png_uint_32)png_ptr->num_palette ||
+ length > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (length == 0)
+ {
+ png_warning(png_ptr, "Zero length tRNS chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ png_crc_read(png_ptr, readbuf, (png_size_t)length);
+ png_ptr->num_trans = (png_uint_16)length;
+ }
+ else
+ {
+ png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_ptr->num_trans = 0;
+ return;
+ }
+
+ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+ &(png_ptr->trans_values));
+}
+#endif
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+void /* PRIVATE */
+png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_size_t truelen;
+ png_byte buf[6];
+
+ png_debug(1, "in png_handle_bKGD\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before bKGD");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid bKGD after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_warning(png_ptr, "Missing PLTE before bKGD");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+ {
+ png_warning(png_ptr, "Duplicate bKGD chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 1;
+ else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ truelen = 6;
+ else
+ truelen = 2;
+
+ if (length != truelen)
+ {
+ png_warning(png_ptr, "Incorrect bKGD chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* We convert the index value into RGB components so that we can allow
+ * arbitrary RGB values for background when we have transparency, and
+ * so it is easy to determine the RGB values of the background color
+ * from the info_ptr struct. */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_ptr->background.index = buf[0];
+ if(info_ptr->num_palette)
+ {
+ if(buf[0] > info_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Incorrect bKGD chunk index value");
+ return;
+ }
+ png_ptr->background.red =
+ (png_uint_16)png_ptr->palette[buf[0]].red;
+ png_ptr->background.green =
+ (png_uint_16)png_ptr->palette[buf[0]].green;
+ png_ptr->background.blue =
+ (png_uint_16)png_ptr->palette[buf[0]].blue;
+ }
+ }
+ else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+ {
+ png_ptr->background.red =
+ png_ptr->background.green =
+ png_ptr->background.blue =
+ png_ptr->background.gray = png_get_uint_16(buf);
+ }
+ else
+ {
+ png_ptr->background.red = png_get_uint_16(buf);
+ png_ptr->background.green = png_get_uint_16(buf + 2);
+ png_ptr->background.blue = png_get_uint_16(buf + 4);
+ }
+
+ png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+}
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+void /* PRIVATE */
+png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ unsigned int num, i;
+ png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_hIST\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before hIST");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid hIST after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_warning(png_ptr, "Missing PLTE before hIST");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+ {
+ png_warning(png_ptr, "Duplicate hIST chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ num = length / 2 ;
+ if (num != (unsigned int) png_ptr->num_palette || num >
+ (unsigned int) PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr, "Incorrect hIST chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[2];
+
+ png_crc_read(png_ptr, buf, 2);
+ readbuf[i] = png_get_uint_16(buf);
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+void /* PRIVATE */
+png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_pHYs\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before pHYs");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid pHYs after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_warning(png_ptr, "Duplicate pHYs chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_warning(png_ptr, "Incorrect pHYs chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ res_x = png_get_uint_32(buf);
+ res_y = png_get_uint_32(buf + 4);
+ unit_type = buf[8];
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+void /* PRIVATE */
+png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_oFFs\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before oFFs");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid oFFs after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_warning(png_ptr, "Duplicate oFFs chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_warning(png_ptr, "Incorrect oFFs chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ offset_x = png_get_int_32(buf);
+ offset_y = png_get_int_32(buf + 4);
+ unit_type = buf[8];
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+/* read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_charp purpose;
+ png_int_32 X0, X1;
+ png_byte type, nparams;
+ png_charp buf, units, endptr;
+ png_charpp params;
+ png_size_t slength;
+ int i;
+
+ png_debug(1, "in png_handle_pCAL\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before pCAL");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid pCAL after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+ {
+ png_warning(png_ptr, "Duplicate pCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
+ length + 1);
+ purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (purpose == NULL)
+ {
+ png_warning(png_ptr, "No memory for pCAL purpose.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)purpose, slength);
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, purpose);
+ return;
+ }
+
+ purpose[slength] = 0x00; /* null terminate the last string */
+
+ png_debug(3, "Finding end of pCAL purpose string\n");
+ for (buf = purpose; *buf; buf++)
+ /* empty loop */ ;
+
+ endptr = purpose + slength;
+
+ /* We need to have at least 12 bytes after the purpose string
+ in order to get the parameter information. */
+ if (endptr <= buf + 12)
+ {
+ png_warning(png_ptr, "Invalid pCAL data");
+ png_free(png_ptr, purpose);
+ return;
+ }
+
+ png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
+ X0 = png_get_int_32((png_bytep)buf+1);
+ X1 = png_get_int_32((png_bytep)buf+5);
+ type = buf[9];
+ nparams = buf[10];
+ units = buf + 11;
+
+ png_debug(3, "Checking pCAL equation type and number of parameters\n");
+ /* Check that we have the right number of parameters for known
+ equation types. */
+ if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+ (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+ (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+ (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+ {
+ png_warning(png_ptr, "Invalid pCAL parameters for equation type");
+ png_free(png_ptr, purpose);
+ return;
+ }
+ else if (type >= PNG_EQUATION_LAST)
+ {
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+ }
+
+ for (buf = units; *buf; buf++)
+ /* Empty loop to move past the units string. */ ;
+
+ png_debug(3, "Allocating pCAL parameters array\n");
+ params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
+ *png_sizeof(png_charp))) ;
+ if (params == NULL)
+ {
+ png_free(png_ptr, purpose);
+ png_warning(png_ptr, "No memory for pCAL params.");
+ return;
+ }
+
+ /* Get pointers to the start of each parameter string. */
+ for (i = 0; i < (int)nparams; i++)
+ {
+ buf++; /* Skip the null string terminator from previous parameter. */
+
+ png_debug1(3, "Reading pCAL parameter %d\n", i);
+ for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
+ /* Empty loop to move past each parameter string */ ;
+
+ /* Make sure we haven't run out of data yet */
+ if (buf > endptr)
+ {
+ png_warning(png_ptr, "Invalid pCAL data");
+ png_free(png_ptr, purpose);
+ png_free(png_ptr, params);
+ return;
+ }
+ }
+
+ png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
+ units, params);
+
+ png_free(png_ptr, purpose);
+ png_free(png_ptr, params);
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+/* read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_charp buffer, ep;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ double width, height;
+ png_charp vp;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_charp swidth, sheight;
+#endif
+#endif
+ png_size_t slength;
+
+ png_debug(1, "in png_handle_sCAL\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sCAL");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sCAL after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ png_warning(png_ptr, "Duplicate sCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
+ length + 1);
+ buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (buffer == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)buffer, slength);
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, buffer);
+ return;
+ }
+
+ buffer[slength] = 0x00; /* null terminate the last string */
+
+ ep = buffer + 1; /* skip unit byte */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ width = png_strtod(png_ptr, ep, &vp);
+ if (*vp)
+ {
+ png_warning(png_ptr, "malformed width string in sCAL chunk");
+ return;
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+ if (swidth == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+ return;
+ }
+ png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+ for (ep = buffer; *ep; ep++)
+ /* empty loop */ ;
+ ep++;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ height = png_strtod(png_ptr, ep, &vp);
+ if (*vp)
+ {
+ png_warning(png_ptr, "malformed height string in sCAL chunk");
+ return;
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+ if (swidth == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+ return;
+ }
+ png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+ if (buffer + slength < ep
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ || width <= 0. || height <= 0.
+#endif
+ )
+ {
+ png_warning(png_ptr, "Invalid sCAL data");
+ png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+ png_free(png_ptr, sheight);
+#endif
+ return;
+ }
+
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
+#endif
+#endif
+
+ png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+ png_free(png_ptr, sheight);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+void /* PRIVATE */
+png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[7];
+ png_time mod_time;
+
+ png_debug(1, "in png_handle_tIME\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Out of place tIME chunk");
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+ {
+ png_warning(png_ptr, "Duplicate tIME chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ if (length != 7)
+ {
+ png_warning(png_ptr, "Incorrect tIME chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 7);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ mod_time.second = buf[6];
+ mod_time.minute = buf[5];
+ mod_time.hour = buf[4];
+ mod_time.day = buf[3];
+ mod_time.month = buf[2];
+ mod_time.year = png_get_uint_16(buf);
+
+ png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp key;
+ png_charp text;
+ png_uint_32 skip = 0;
+ png_size_t slength;
+ int ret;
+
+ png_debug(1, "in png_handle_tEXt\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before tEXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ key = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (key == NULL)
+ {
+ png_warning(png_ptr, "No memory to process text chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)key, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, key);
+ return;
+ }
+
+ key[slength] = 0x00;
+
+ for (text = key; *text; text++)
+ /* empty loop to find end of key */ ;
+
+ if (text != key + slength)
+ text++;
+
+ text_ptr = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr, "Not enough memory to process text chunk.");
+ png_free(png_ptr, key);
+ return;
+ }
+ text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+ text_ptr->itxt_length = 0;
+#endif
+ text_ptr->text = text;
+ text_ptr->text_length = png_strlen(text);
+
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to process text chunk.");
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp chunkdata;
+ png_charp text;
+ int comp_type;
+ int ret;
+ png_size_t slength, prefix_len, data_len;
+
+ png_debug(1, "in png_handle_zTXt\n");
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before zTXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We will no doubt have problems with chunks even half this size, but
+ there is no hard and fast rule to tell us where to stop. */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr,"zTXt chunk too large to fit in memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (chunkdata == NULL)
+ {
+ png_warning(png_ptr,"Out of memory processing zTXt chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (text = chunkdata; *text; text++)
+ /* empty loop */ ;
+
+ /* zTXt must have some text after the chunkdataword */
+ if (text == chunkdata + slength - 1)
+ {
+ png_warning(png_ptr, "Truncated zTXt chunk");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+ else
+ {
+ comp_type = *(++text);
+ if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
+ {
+ png_warning(png_ptr, "Unknown compression type in zTXt chunk");
+ comp_type = PNG_TEXT_COMPRESSION_zTXt;
+ }
+ text++; /* skip the compression_method byte */
+ }
+ prefix_len = text - chunkdata;
+
+ chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
+ (png_size_t)length, prefix_len, &data_len);
+
+ text_ptr = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+ text_ptr->compression = comp_type;
+ text_ptr->key = chunkdata;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+ text_ptr->itxt_length = 0;
+#endif
+ text_ptr->text = chunkdata + prefix_len;
+ text_ptr->text_length = data_len;
+
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, text_ptr);
+ png_free(png_ptr, chunkdata);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp chunkdata;
+ png_charp key, lang, text, lang_key;
+ int comp_flag;
+ int comp_type = 0;
+ int ret;
+ png_size_t slength, prefix_len, data_len;
+
+ png_debug(1, "in png_handle_iTXt\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before iTXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We will no doubt have problems with chunks even half this size, but
+ there is no hard and fast rule to tell us where to stop. */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr,"iTXt chunk too large to fit in memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (chunkdata == NULL)
+ {
+ png_warning(png_ptr, "No memory to process iTXt chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (lang = chunkdata; *lang; lang++)
+ /* empty loop */ ;
+ lang++; /* skip NUL separator */
+
+ /* iTXt must have a language tag (possibly empty), two compression bytes,
+ translated keyword (possibly empty), and possibly some text after the
+ keyword */
+
+ if (lang >= chunkdata + slength - 3)
+ {
+ png_warning(png_ptr, "Truncated iTXt chunk");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+ else
+ {
+ comp_flag = *lang++;
+ comp_type = *lang++;
+ }
+
+ for (lang_key = lang; *lang_key; lang_key++)
+ /* empty loop */ ;
+ lang_key++; /* skip NUL separator */
+
+ for (text = lang_key; *text; text++)
+ /* empty loop */ ;
+ text++; /* skip NUL separator */
+ if (text >= chunkdata + slength)
+ {
+ png_warning(png_ptr, "Malformed iTXt chunk");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ prefix_len = text - chunkdata;
+
+ key=chunkdata;
+ if (comp_flag)
+ chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
+ (size_t)length, prefix_len, &data_len);
+ else
+ data_len=png_strlen(chunkdata + prefix_len);
+ text_ptr = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+ text_ptr->compression = (int)comp_flag + 1;
+ text_ptr->lang_key = chunkdata+(lang_key-key);
+ text_ptr->lang = chunkdata+(lang-key);
+ text_ptr->itxt_length = data_len;
+ text_ptr->text_length = 0;
+ text_ptr->key = chunkdata;
+ text_ptr->text = chunkdata + prefix_len;
+
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, text_ptr);
+ png_free(png_ptr, chunkdata);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
+}
+#endif
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+void /* PRIVATE */
+png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte data[8];
+ png_uint_32 num_frames;
+ png_uint_32 num_plays;
+ png_uint_32 didSet;
+
+ png_debug(1, "in png_handle_acTL\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ {
+ png_error(png_ptr, "Missing IHDR before acTL");
+ }
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid acTL after IDAT skipped");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_acTL)
+ {
+ png_warning(png_ptr, "Duplicate acTL skipped");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (length != 8)
+ {
+ png_warning(png_ptr, "acTL with invalid length skipped");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, data, 8);
+ png_crc_finish(png_ptr, 0);
+
+ num_frames = png_get_uint_31(png_ptr, data);
+ num_plays = png_get_uint_31(png_ptr, data + 4);
+
+ /* the set function will do error checking on num_frames */
+ didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
+ if(didSet)
+ png_ptr->mode |= PNG_HAVE_acTL;
+}
+
+void /* PRIVATE */
+png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte data[22];
+ png_uint_32 width;
+ png_uint_32 height;
+ png_uint_32 x_offset;
+ png_uint_32 y_offset;
+ png_uint_16 delay_num;
+ png_uint_16 delay_den;
+ png_byte dispose_op;
+ png_byte blend_op;
+
+ png_debug(1, "in png_handle_fcTL\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ {
+ png_error(png_ptr, "Missing IHDR before fcTL");
+ }
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ /* for any frames other then the first this message may be misleading,
+ * but correct. PNG_HAVE_IDAT is unset before the frame head is read
+ * i can't think of a better message */
+ png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_fcTL)
+ {
+ png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (length != 26)
+ {
+ png_warning(png_ptr, "fcTL with invalid length skipped");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_ensure_sequence_number(png_ptr, length);
+
+ png_crc_read(png_ptr, data, 22);
+ png_crc_finish(png_ptr, 0);
+
+ width = png_get_uint_31(png_ptr, data);
+ height = png_get_uint_31(png_ptr, data + 4);
+ x_offset = png_get_uint_31(png_ptr, data + 8);
+ y_offset = png_get_uint_31(png_ptr, data + 12);
+ delay_num = png_get_uint_16(data + 16);
+ delay_den = png_get_uint_16(data + 18);
+ dispose_op = data[20];
+ blend_op = data[21];
+
+ if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
+ png_error(png_ptr, "fcTL for the first frame must have zero offset");
+ if (png_ptr->num_frames_read == 0 &&
+ (width != info_ptr->width || height != info_ptr->height))
+ png_error(png_ptr, "size in first frame's fcTL must match "
+ "the size in IHDR");
+
+ /* the set function will do more error checking */
+ png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
+ x_offset, y_offset, delay_num, delay_den,
+ dispose_op, blend_op);
+
+ png_read_reinit(png_ptr, info_ptr);
+
+ png_ptr->mode |= PNG_HAVE_fcTL;
+}
+
+void /* PRIVATE */
+png_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+ if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
+ {
+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
+ info_ptr->num_frames++;
+ }
+}
+
+void /* PRIVATE */
+png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_ensure_sequence_number(png_ptr, length);
+
+ /* This function is only called from png_read_end(), png_read_info(),
+ * and png_push_read_chunk() which means that:
+ * - the user doesn't want to read this frame
+ * - or this is an out-of-place fdAT
+ * in either case it is safe to ignore the chunk with a warning */
+ png_warning(png_ptr, "ignoring fdAT chunk");
+ png_crc_finish(png_ptr, length - 4);
+}
+
+void /* PRIVATE */
+png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
+{
+ png_byte data[4];
+ png_uint_32 sequence_number;
+
+ if (length < 4)
+ png_error(png_ptr, "invalid fcTL or fdAT chunk found");
+
+ png_crc_read(png_ptr, data, 4);
+ sequence_number = png_get_uint_31(png_ptr, data);
+
+ if (sequence_number != png_ptr->next_seq_num)
+ png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
+ "number found");
+
+ png_ptr->next_seq_num++;
+}
+#endif /* PNG_READ_APNG_SUPPORTED */
+
+/* This function is called when we haven't found a handler for a
+ chunk. If there isn't a problem with the chunk itself (ie bad
+ chunk name, CRC, or a critical chunk), the chunk is silently ignored
+ -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
+ case it will be saved away to be written out later. */
+void /* PRIVATE */
+png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_uint_32 skip = 0;
+
+ png_debug(1, "in png_handle_unknown\n");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IDAT;
+#endif
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ {
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ && png_ptr->read_user_chunk_fn == NULL
+#endif
+ )
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
+ (png_ptr->read_user_chunk_fn != NULL))
+ {
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "unknown chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+ png_strncpy((png_charp)png_ptr->unknown_chunk.name,
+ (png_charp)png_ptr->chunk_name,
+ png_sizeof((png_charp)png_ptr->chunk_name));
+ png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
+ png_ptr->unknown_chunk.size = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ if(png_ptr->read_user_chunk_fn != NULL)
+ {
+ /* callback to user unknown chunk handler */
+ int ret;
+ ret = (*(png_ptr->read_user_chunk_fn))
+ (png_ptr, &png_ptr->unknown_chunk);
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+ if (ret == 0)
+ {
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS)
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ }
+ }
+#else
+ png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+#endif
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+ else
+#endif
+ skip = length;
+
+ png_crc_finish(png_ptr, skip);
+
+#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
+#endif
+}
+
+/* This function is called to verify that a chunk name is valid.
+ This function can't have the "critical chunk check" incorporated
+ into it, since in the future we will need to be able to call user
+ functions to handle unknown critical chunks after we check that
+ the chunk name itself is valid. */
+
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+
+void /* PRIVATE */
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+ png_debug(1, "in png_check_chunk_name\n");
+ if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
+ isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
+ {
+ png_chunk_error(png_ptr, "invalid chunk type");
+ }
+}
+
+/* Combines the row recently read in with the existing pixels in the
+ row. This routine takes care of alpha and transparency if requested.
+ This routine also handles the two methods of progressive display
+ of interlaced images, depending on the mask value.
+ The mask value describes which pixels are to be combined with
+ the row. The pattern always repeats every 8 pixels, so just 8
+ bits are needed. A one indicates the pixel is to be combined,
+ a zero indicates the pixel is to be skipped. This is in addition
+ to any alpha or transparency value associated with the pixel. If
+ you want all pixels to be combined, pass 0xff (255) in mask. */
+
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int mask)
+{
+ png_debug(1,"in png_combine_row\n");
+ if (mask == 0xff)
+ {
+ png_memcpy(row, png_ptr->row_buf + 1,
+ PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
+ }
+ else
+ {
+ switch (png_ptr->row_info.pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_inc, s_start, s_end;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+ else
+#endif
+ {
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ int value;
+
+ value = (*sp >> shift) & 0x01;
+ *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_start, s_end, s_inc;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ int value;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+ else
+#endif
+ {
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_start, s_end, s_inc;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ int value;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+ else
+#endif
+ {
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ value = (*sp >> shift) & 0xf;
+ *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ default:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ png_byte m = 0x80;
+
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ png_memcpy(dp, sp, pixel_bytes);
+ }
+
+ sp += pixel_bytes;
+ dp += pixel_bytes;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ }
+ }
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* OLD pre-1.0.9 interface:
+void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+ png_uint_32 transformations)
+ */
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+ png_row_infop row_info = &(png_ptr->row_info);
+ png_bytep row = png_ptr->row_buf + 1;
+ int pass = png_ptr->pass;
+ png_uint_32 transformations = png_ptr->transformations;
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+ /* offset to next interlace block */
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+ png_debug(1,"in png_do_read_interlace\n");
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)((row_info->width + 7) & 0x07);
+ dshift = (int)((final_width + 7) & 0x07);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+ else
+#endif
+ {
+ sshift = 7 - (int)((row_info->width + 7) & 0x07);
+ dshift = 7 - (int)((final_width + 7) & 0x07);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x01);
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+ png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+ dshift = (int)(((final_width + 3) & 0x03) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+ else
+#endif
+ {
+ sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+ dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x03);
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+ int jstop = png_pass_inc[pass];
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+ dshift = (int)(((final_width + 1) & 0x01) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ else
+#endif
+ {
+ sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+ dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v = (png_byte)((*sp >> sshift) & 0xf);
+ int j;
+
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ default:
+ {
+ png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+ png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
+ png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v[8];
+ int j;
+
+ png_memcpy(v, sp, pixel_bytes);
+ for (j = 0; j < jstop; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sp -= pixel_bytes;
+ }
+ break;
+ }
+ }
+ row_info->width = final_width;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
+ }
+#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ transformations = transformations; /* silence compiler warning */
+#endif
+}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+ png_bytep prev_row, int filter)
+{
+ png_debug(1, "in png_read_filter_row\n");
+ png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
+ switch (filter)
+ {
+ case PNG_FILTER_VALUE_NONE:
+ break;
+ case PNG_FILTER_VALUE_SUB:
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+ png_bytep lp = row;
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_UP:
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_AVG:
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *lp++) / 2 ) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_PAETH:
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_bytep cp = prev_row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop=row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++) /* use leftover rp,pp */
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ a = *lp++;
+ b = *pp++;
+ c = *cp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ /*
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+ */
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ default:
+ png_warning(png_ptr, "Ignoring bad adaptive filter type");
+ *row=0;
+ break;
+ }
+}
+
+void /* PRIVATE */
+png_read_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_debug(1, "in png_read_finish_row\n");
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ png_memset_check(png_ptr, png_ptr->prev_row, 0,
+ png_ptr->rowbytes + 1);
+ do
+ {
+ png_ptr->pass++;
+ if (png_ptr->pass >= 7)
+ break;
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1;
+
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ if (!(png_ptr->num_rows))
+ continue;
+ }
+ else /* if (png_ptr->transformations & PNG_INTERLACE) */
+ break;
+ } while (png_ptr->iwidth == 0);
+
+ if (png_ptr->pass < 7)
+ return;
+ }
+
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IDAT;
+#endif
+ char extra;
+ int ret;
+
+ png_ptr->zstream.next_out = (Byte *)&extra;
+ png_ptr->zstream.avail_out = (uInt)1;
+ for(;;)
+ {
+ if (!(png_ptr->zstream.avail_in))
+ {
+ while (!png_ptr->idat_size)
+ {
+ png_byte chunk_length[4];
+
+ png_crc_finish(png_ptr, 0);
+
+ png_read_data(png_ptr, chunk_length, 4);
+ png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ png_error(png_ptr, "Not enough image data");
+
+ }
+ png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_in = png_ptr->zbuf;
+ if (png_ptr->zbuf_size > png_ptr->idat_size)
+ png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+ png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
+ png_ptr->idat_size -= png_ptr->zstream.avail_in;
+ }
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret == Z_STREAM_END)
+ {
+ if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
+ png_ptr->idat_size)
+ png_warning(png_ptr, "Extra compressed data");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ if (ret != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+ "Decompression Error");
+
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_warning(png_ptr, "Extra compressed data.");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+
+ }
+ png_ptr->zstream.avail_out = 0;
+ }
+
+ if (png_ptr->idat_size || png_ptr->zstream.avail_in)
+ png_warning(png_ptr, "Extra compression data");
+
+ inflateReset(&png_ptr->zstream);
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+}
+
+void /* PRIVATE */
+png_read_start_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int max_pixel_depth;
+ png_uint_32 row_bytes;
+
+ png_debug(1, "in png_read_start_row\n");
+ png_ptr->zstream.avail_in = 0;
+ png_init_read_transformations(png_ptr);
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ else
+ png_ptr->num_rows = png_ptr->height;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
+
+ png_ptr->irowbytes = (png_size_t)row_bytes;
+ if((png_uint_32)png_ptr->irowbytes != row_bytes)
+ png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
+ }
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->iwidth = png_ptr->width;
+ png_ptr->irowbytes = png_ptr->rowbytes + 1;
+ }
+ max_pixel_depth = png_ptr->pixel_depth;
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+ max_pixel_depth = 8;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 24;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth < 8)
+ max_pixel_depth = 8;
+ if (png_ptr->num_trans)
+ max_pixel_depth *= 2;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (png_ptr->num_trans)
+ {
+ max_pixel_depth *= 4;
+ max_pixel_depth /= 3;
+ }
+ }
+ }
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & (PNG_FILLER))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ max_pixel_depth = 32;
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth <= 8)
+ max_pixel_depth = 16;
+ else
+ max_pixel_depth = 32;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (max_pixel_depth <= 32)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 64;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ {
+ if (
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+#endif
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ (png_ptr->transformations & (PNG_FILLER)) ||
+#endif
+ png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (max_pixel_depth <= 16)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 64;
+ }
+ else
+ {
+ if (max_pixel_depth <= 8)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 24;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 64;
+ else
+ max_pixel_depth = 48;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if(png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ int user_pixel_depth=png_ptr->user_transform_depth*
+ png_ptr->user_transform_channels;
+ if(user_pixel_depth > max_pixel_depth)
+ max_pixel_depth=user_pixel_depth;
+ }
+#endif
+
+ /* align the width on the next larger 8 pixels. Mainly used
+ for interlacing */
+ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+ /* calculate the maximum bytes needed, adding a byte and a pixel
+ for safety's sake */
+ row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
+ 1 + ((max_pixel_depth + 7) >> 3);
+#ifdef PNG_MAX_MALLOC_64K
+ if (row_bytes > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+ if (png_ptr->big_row_buf == NULL)
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
+ if (png_ptr->row_buf == NULL)
+ png_ptr->row_buf = png_ptr->big_row_buf+32;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+ if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
+ png_error(png_ptr, "Row has too many bytes to allocate in memory.");
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+ png_ptr->rowbytes + 1));
+
+ png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ png_debug1(3, "width = %lu,\n", png_ptr->width);
+ png_debug1(3, "height = %lu,\n", png_ptr->height);
+ png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
+ png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
+ png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
+ png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
+
+ png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
+
+#if defined(PNG_READ_APNG_SUPPORTED)
+/* This function is to be called after the main IDAT set has been read and
+ * before a new IDAT is read. It resets some parts of png_ptr
+ * to make them usable by the read functions again */
+void /* PRIVATE */
+png_read_reset(png_structp png_ptr)
+{
+ png_ptr->mode &= ~PNG_HAVE_IDAT;
+ png_ptr->mode &= ~PNG_AFTER_IDAT;
+ png_ptr->row_number = 0;
+ png_ptr->pass = 0;
+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+
+void /* PRIVATE */
+png_read_reinit(png_structp png_ptr, png_infop info_ptr)
+{
+ png_ptr->width = info_ptr->next_frame_width;
+ png_ptr->height = info_ptr->next_frame_height;
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
+}
+
+/* same as png_read_reset() but for the progressive reader */
+void /* PRIVATE */
+png_progressive_read_reset(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* start of interlace block */
+ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+ png_uint_32 row_bytes;
+
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ else
+ png_ptr->num_rows = png_ptr->height;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
+
+ png_ptr->irowbytes = (png_size_t)row_bytes;
+ if((png_uint_32)png_ptr->irowbytes != row_bytes)
+ png_error(png_ptr, "png_progressive_read_reset(): Rowbytes "
+ "overflow");
+ }
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->iwidth = png_ptr->width;
+ png_ptr->irowbytes = png_ptr->rowbytes + 1;
+ }
+
+ png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED;
+ if (inflateReset(&(png_ptr->zstream)) != Z_OK)
+ png_error(png_ptr, "inflateReset failed");
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.next_in = 0;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+}
+#endif /* PNG_READ_APNG_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngset.c b/kernel/kls_png/ksquirrel-libs-png/pngset.c
new file mode 100644
index 0000000..b16af79
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngset.c
@@ -0,0 +1,1383 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * Last changed in libpng 1.2.17 May 15, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file. This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#if defined(PNG_bKGD_SUPPORTED)
+void PNGAPI
+png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
+{
+ png_debug1(1, "in %s storage function\n", "bKGD");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
+ info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
+ double white_x, double white_y, double red_x, double red_y,
+ double green_x, double green_y, double blue_x, double blue_y)
+{
+ png_debug1(1, "in %s storage function\n", "cHRM");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (white_x < 0.0 || white_y < 0.0 ||
+ red_x < 0.0 || red_y < 0.0 ||
+ green_x < 0.0 || green_y < 0.0 ||
+ blue_x < 0.0 || blue_y < 0.0)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set negative chromaticity value");
+ return;
+ }
+ if (white_x > 21474.83 || white_y > 21474.83 ||
+ red_x > 21474.83 || red_y > 21474.83 ||
+ green_x > 21474.83 || green_y > 21474.83 ||
+ blue_x > 21474.83 || blue_y > 21474.83)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set chromaticity value exceeding 21474.83");
+ return;
+ }
+
+ info_ptr->x_white = (float)white_x;
+ info_ptr->y_white = (float)white_y;
+ info_ptr->x_red = (float)red_x;
+ info_ptr->y_red = (float)red_y;
+ info_ptr->x_green = (float)green_x;
+ info_ptr->y_green = (float)green_y;
+ info_ptr->x_blue = (float)blue_x;
+ info_ptr->y_blue = (float)blue_y;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
+ info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
+ info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5);
+ info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5);
+ info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
+ info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
+ info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5);
+ info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5);
+#endif
+ info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+ png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+ png_fixed_point blue_x, png_fixed_point blue_y)
+{
+ png_debug1(1, "in %s storage function\n", "cHRM");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (white_x < 0 || white_y < 0 ||
+ red_x < 0 || red_y < 0 ||
+ green_x < 0 || green_y < 0 ||
+ blue_x < 0 || blue_y < 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set negative chromaticity value");
+ return;
+ }
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ if (white_x > (double) PNG_UINT_31_MAX ||
+ white_y > (double) PNG_UINT_31_MAX ||
+ red_x > (double) PNG_UINT_31_MAX ||
+ red_y > (double) PNG_UINT_31_MAX ||
+ green_x > (double) PNG_UINT_31_MAX ||
+ green_y > (double) PNG_UINT_31_MAX ||
+ blue_x > (double) PNG_UINT_31_MAX ||
+ blue_y > (double) PNG_UINT_31_MAX)
+#else
+ if (white_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ white_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ red_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ red_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ green_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ green_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ blue_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
+ blue_y > (png_fixed_point) PNG_UINT_31_MAX/100000L)
+#endif
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set chromaticity value exceeding 21474.83");
+ return;
+ }
+ info_ptr->int_x_white = white_x;
+ info_ptr->int_y_white = white_y;
+ info_ptr->int_x_red = red_x;
+ info_ptr->int_y_red = red_y;
+ info_ptr->int_x_green = green_x;
+ info_ptr->int_y_green = green_y;
+ info_ptr->int_x_blue = blue_x;
+ info_ptr->int_y_blue = blue_y;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->x_white = (float)(white_x/100000.);
+ info_ptr->y_white = (float)(white_y/100000.);
+ info_ptr->x_red = (float)( red_x/100000.);
+ info_ptr->y_red = (float)( red_y/100000.);
+ info_ptr->x_green = (float)(green_x/100000.);
+ info_ptr->y_green = (float)(green_y/100000.);
+ info_ptr->x_blue = (float)( blue_x/100000.);
+ info_ptr->y_blue = (float)( blue_y/100000.);
+#endif
+ info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
+{
+ double gamma;
+ png_debug1(1, "in %s storage function\n", "gAMA");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Check for overflow */
+ if (file_gamma > 21474.83)
+ {
+ png_warning(png_ptr, "Limiting gamma to 21474.83");
+ gamma=21474.83;
+ }
+ else
+ gamma=file_gamma;
+ info_ptr->gamma = (float)gamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = (int)(gamma*100000.+.5);
+#endif
+ info_ptr->valid |= PNG_INFO_gAMA;
+ if(gamma == 0.0)
+ png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+void PNGAPI
+png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
+ int_gamma)
+{
+ png_fixed_point gamma;
+
+ png_debug1(1, "in %s storage function\n", "gAMA");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Limiting gamma to 21474.83");
+ gamma=PNG_UINT_31_MAX;
+ }
+ else
+ {
+ if (int_gamma < 0)
+ {
+ png_warning(png_ptr, "Setting negative gamma to zero");
+ gamma=0;
+ }
+ else
+ gamma=int_gamma;
+ }
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->gamma = (float)(gamma/100000.);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = gamma;
+#endif
+ info_ptr->valid |= PNG_INFO_gAMA;
+ if(gamma == 0)
+ png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+void PNGAPI
+png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function\n", "hIST");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+ if (info_ptr->num_palette <= 0 || info_ptr->num_palette
+ > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr,
+ "Invalid palette size, hIST allocation skipped.");
+ return;
+ }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+#endif
+ /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in version
+ 1.2.1 */
+ png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
+ (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof (png_uint_16)));
+ if (png_ptr->hist == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
+ return;
+ }
+
+ for (i = 0; i < info_ptr->num_palette; i++)
+ png_ptr->hist[i] = hist[i];
+ info_ptr->hist = png_ptr->hist;
+ info_ptr->valid |= PNG_INFO_hIST;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_HIST;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ png_debug1(1, "in %s storage function\n", "IHDR");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* check for width and height valid values */
+ if (width == 0 || height == 0)
+ png_error(png_ptr, "Image width or height is zero in IHDR");
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
+ png_error(png_ptr, "image size exceeds user limits in IHDR");
+#else
+ if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
+ png_error(png_ptr, "image size exceeds user limits in IHDR");
+#endif
+ if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
+ png_error(png_ptr, "Invalid image size in IHDR");
+ if ( width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 64 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ png_warning(png_ptr, "Width is too large for libpng to process pixels");
+
+ /* check other values */
+ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+ bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth in IHDR");
+
+ if (color_type < 0 || color_type == 1 ||
+ color_type == 5 || color_type > 6)
+ png_error(png_ptr, "Invalid color type in IHDR");
+
+ if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+ ((color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+ png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
+
+ if (interlace_type >= PNG_INTERLACE_LAST)
+ png_error(png_ptr, "Unknown interlace method in IHDR");
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_error(png_ptr, "Unknown compression method in IHDR");
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ /* Accept filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not read a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
+ png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
+ if(filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+ png_error(png_ptr, "Unknown filter method in IHDR");
+ if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
+ png_warning(png_ptr, "Invalid filter method in IHDR");
+ }
+#else
+ if(filter_type != PNG_FILTER_TYPE_BASE)
+ png_error(png_ptr, "Unknown filter method in IHDR");
+#endif
+
+ info_ptr->width = width;
+ info_ptr->height = height;
+ info_ptr->bit_depth = (png_byte)bit_depth;
+ info_ptr->color_type =(png_byte) color_type;
+ info_ptr->compression_type = (png_byte)compression_type;
+ info_ptr->filter_type = (png_byte)filter_type;
+ info_ptr->interlace_type = (png_byte)interlace_type;
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+ else
+ info_ptr->channels = 1;
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+ /* check for potential overflow */
+ if (width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 64 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ info_ptr->rowbytes = (png_size_t)0;
+ else
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
+
+#if defined(PNG_APNG_SUPPORTED)
+ /* for non-animated png. this may be overritten from an acTL chunk later */
+ info_ptr->num_frames = 1;
+#endif
+}
+
+#if defined(PNG_oFFs_SUPPORTED)
+void PNGAPI
+png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
+ png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function\n", "oFFs");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_offset = offset_x;
+ info_ptr->y_offset = offset_y;
+ info_ptr->offset_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+void PNGAPI
+png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_charp units, png_charpp params)
+{
+ png_uint_32 length;
+ int i;
+
+ png_debug1(1, "in %s storage function\n", "pCAL");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ length = png_strlen(purpose) + 1;
+ png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
+ info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_purpose == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
+
+ png_debug(3, "storing X0, X1, type, and nparams in info\n");
+ info_ptr->pcal_X0 = X0;
+ info_ptr->pcal_X1 = X1;
+ info_ptr->pcal_type = (png_byte)type;
+ info_ptr->pcal_nparams = (png_byte)nparams;
+
+ length = png_strlen(units) + 1;
+ png_debug1(3, "allocating units for info (%lu bytes)\n", length);
+ info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_units == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL units.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
+
+ info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
+ (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
+ if (info_ptr->pcal_params == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL params.");
+ return;
+ }
+
+ info_ptr->pcal_params[nparams] = NULL;
+
+ for (i = 0; i < nparams; i++)
+ {
+ length = png_strlen(params[i]) + 1;
+ png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
+ info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_params[i] == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
+ }
+
+ info_ptr->valid |= PNG_INFO_pCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_PCAL;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+ int unit, double width, double height)
+{
+ png_debug1(1, "in %s storage function\n", "sCAL");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->scal_unit = (png_byte)unit;
+ info_ptr->scal_pixel_width = width;
+ info_ptr->scal_pixel_height = height;
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+ int unit, png_charp swidth, png_charp sheight)
+{
+ png_uint_32 length;
+
+ png_debug1(1, "in %s storage function\n", "sCAL");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->scal_unit = (png_byte)unit;
+
+ length = png_strlen(swidth) + 1;
+ png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+ info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->scal_s_width == NULL)
+ {
+ png_warning(png_ptr,
+ "Memory allocation failed while processing sCAL.");
+ }
+ png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
+
+ length = png_strlen(sheight) + 1;
+ png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+ info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->scal_s_height == NULL)
+ {
+ png_free (png_ptr, info_ptr->scal_s_width);
+ png_warning(png_ptr,
+ "Memory allocation failed while processing sCAL.");
+ }
+ png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_SCAL;
+#endif
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+void PNGAPI
+png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function\n", "pHYs");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_pixels_per_unit = res_x;
+ info_ptr->y_pixels_per_unit = res_y;
+ info_ptr->phys_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
+ png_colorp palette, int num_palette)
+{
+
+ png_debug1(1, "in %s storage function\n", "PLTE");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Invalid palette length");
+ else
+ {
+ png_warning(png_ptr, "Invalid palette length");
+ return;
+ }
+ }
+
+ /*
+ * It may not actually be necessary to set png_ptr->palette here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+#endif
+
+ /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+ of num_palette entries,
+ in case of an invalid PNG file that has too-large sample values. */
+ png_ptr->palette = (png_colorp)png_malloc(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
+ png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH *
+ png_sizeof(png_color));
+ png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
+ info_ptr->palette = png_ptr->palette;
+ info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_PLTE;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_PLTE;
+#endif
+
+ info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#if defined(PNG_sBIT_SUPPORTED)
+void PNGAPI
+png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
+ png_color_8p sig_bit)
+{
+ png_debug1(1, "in %s storage function\n", "sBIT");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
+ info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+void PNGAPI
+png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
+{
+ png_debug1(1, "in %s storage function\n", "sRGB");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->srgb_intent = (png_byte)intent;
+ info_ptr->valid |= PNG_INFO_sRGB;
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
+ int intent)
+{
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float file_gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_fixed_point int_file_gamma;
+#endif
+#endif
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+ int_green_y, int_blue_x, int_blue_y;
+#endif
+#endif
+ png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_set_sRGB(png_ptr, info_ptr, intent);
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ file_gamma = (float).45455;
+ png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ int_file_gamma = 45455L;
+ png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
+#endif
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ int_white_x = 31270L;
+ int_white_y = 32900L;
+ int_red_x = 64000L;
+ int_red_y = 33000L;
+ int_green_x = 30000L;
+ int_green_y = 60000L;
+ int_blue_x = 15000L;
+ int_blue_y = 6000L;
+
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
+ int_blue_x, int_blue_y);
+#endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ white_x = (float).3127;
+ white_y = (float).3290;
+ red_x = (float).64;
+ red_y = (float).33;
+ green_x = (float).30;
+ green_y = (float).60;
+ blue_x = (float).15;
+ blue_y = (float).06;
+
+ png_set_cHRM(png_ptr, info_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#endif
+}
+#endif
+
+
+#if defined(PNG_iCCP_SUPPORTED)
+void PNGAPI
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+ png_charp name, int compression_type,
+ png_charp profile, png_uint_32 proflen)
+{
+ png_charp new_iccp_name;
+ png_charp new_iccp_profile;
+
+ png_debug1(1, "in %s storage function\n", "iCCP");
+ if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+ return;
+
+ new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
+ if (new_iccp_name == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
+ return;
+ }
+ png_strncpy(new_iccp_name, name, png_sizeof(new_iccp_name));
+ new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
+ if (new_iccp_profile == NULL)
+ {
+ png_free (png_ptr, new_iccp_name);
+ png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
+ return;
+ }
+ png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_proflen = proflen;
+ info_ptr->iccp_name = new_iccp_name;
+ info_ptr->iccp_profile = new_iccp_profile;
+ /* Compression is always zero but is here so the API and info structure
+ * does not have to change if we introduce multiple compression types */
+ info_ptr->iccp_compression = (png_byte)compression_type;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_ICCP;
+#endif
+ info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+void PNGAPI
+png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+ int num_text)
+{
+ int ret;
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+ int num_text)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
+ "text" : (png_const_charp)png_ptr->chunk_name));
+
+ if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
+ return(0);
+
+ /* Make sure we have enough space in the "text" array in info_struct
+ * to hold all of the incoming text_ptr objects.
+ */
+ if (info_ptr->num_text + num_text > info_ptr->max_text)
+ {
+ if (info_ptr->text != NULL)
+ {
+ png_textp old_text;
+ int old_max;
+
+ old_max = info_ptr->max_text;
+ info_ptr->max_text = info_ptr->num_text + num_text + 8;
+ old_text = info_ptr->text;
+ info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
+ if (info_ptr->text == NULL)
+ {
+ png_free(png_ptr, old_text);
+ return(1);
+ }
+ png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
+ png_sizeof(png_text)));
+ png_free(png_ptr, old_text);
+ }
+ else
+ {
+ info_ptr->max_text = num_text + 8;
+ info_ptr->num_text = 0;
+ info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
+ if (info_ptr->text == NULL)
+ return(1);
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_TEXT;
+#endif
+ }
+ png_debug1(3, "allocated %d entries for info_ptr->text\n",
+ info_ptr->max_text);
+ }
+ for (i = 0; i < num_text; i++)
+ {
+ png_size_t text_length,key_len;
+ png_size_t lang_len,lang_key_len;
+ png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+ if (text_ptr[i].key == NULL)
+ continue;
+
+ key_len = png_strlen(text_ptr[i].key);
+
+ if(text_ptr[i].compression <= 0)
+ {
+ lang_len = 0;
+ lang_key_len = 0;
+ }
+ else
+#ifdef PNG_iTXt_SUPPORTED
+ {
+ /* set iTXt data */
+ if (text_ptr[i].lang != NULL)
+ lang_len = png_strlen(text_ptr[i].lang);
+ else
+ lang_len = 0;
+ if (text_ptr[i].lang_key != NULL)
+ lang_key_len = png_strlen(text_ptr[i].lang_key);
+ else
+ lang_key_len = 0;
+ }
+#else
+ {
+ png_warning(png_ptr, "iTXt chunk not supported.");
+ continue;
+ }
+#endif
+
+ if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+ {
+ text_length = 0;
+#ifdef PNG_iTXt_SUPPORTED
+ if(text_ptr[i].compression > 0)
+ textp->compression = PNG_ITXT_COMPRESSION_NONE;
+ else
+#endif
+ textp->compression = PNG_TEXT_COMPRESSION_NONE;
+ }
+ else
+ {
+ text_length = png_strlen(text_ptr[i].text);
+ textp->compression = text_ptr[i].compression;
+ }
+
+ textp->key = (png_charp)png_malloc_warn(png_ptr,
+ (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
+ if (textp->key == NULL)
+ return(1);
+ png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
+ (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
+ (int)textp->key);
+
+ png_memcpy(textp->key, text_ptr[i].key,
+ (png_size_t)(key_len));
+ *(textp->key+key_len) = '\0';
+#ifdef PNG_iTXt_SUPPORTED
+ if (text_ptr[i].compression > 0)
+ {
+ textp->lang=textp->key + key_len + 1;
+ png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
+ *(textp->lang+lang_len) = '\0';
+ textp->lang_key=textp->lang + lang_len + 1;
+ png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+ *(textp->lang_key+lang_key_len) = '\0';
+ textp->text=textp->lang_key + lang_key_len + 1;
+ }
+ else
+#endif
+ {
+#ifdef PNG_iTXt_SUPPORTED
+ textp->lang=NULL;
+ textp->lang_key=NULL;
+#endif
+ textp->text=textp->key + key_len + 1;
+ }
+ if(text_length)
+ png_memcpy(textp->text, text_ptr[i].text,
+ (png_size_t)(text_length));
+ *(textp->text+text_length) = '\0';
+
+#ifdef PNG_iTXt_SUPPORTED
+ if(textp->compression > 0)
+ {
+ textp->text_length = 0;
+ textp->itxt_length = text_length;
+ }
+ else
+#endif
+ {
+ textp->text_length = text_length;
+#ifdef PNG_iTXt_SUPPORTED
+ textp->itxt_length = 0;
+#endif
+ }
+ info_ptr->num_text++;
+ png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
+ }
+ return(0);
+}
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+void PNGAPI
+png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
+{
+ png_debug1(1, "in %s storage function\n", "tIME");
+ if (png_ptr == NULL || info_ptr == NULL ||
+ (png_ptr->mode & PNG_WROTE_tIME))
+ return;
+
+ png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
+ info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+void PNGAPI
+png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
+ png_bytep trans, int num_trans, png_color_16p trans_values)
+{
+ png_debug1(1, "in %s storage function\n", "tRNS");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (trans != NULL)
+ {
+ /*
+ * It may not actually be necessary to set png_ptr->trans here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+#endif
+ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+ png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)PNG_MAX_PALETTE_LENGTH);
+ if (num_trans <= PNG_MAX_PALETTE_LENGTH)
+ png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_TRNS;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_TRNS;
+#endif
+ }
+
+ if (trans_values != NULL)
+ {
+ png_memcpy(&(info_ptr->trans_values), trans_values,
+ png_sizeof(png_color_16));
+ if (num_trans == 0)
+ num_trans = 1;
+ }
+ info_ptr->num_trans = (png_uint_16)num_trans;
+ info_ptr->valid |= PNG_INFO_tRNS;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+void PNGAPI
+png_set_sPLT(png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tp entries, int nentries)
+{
+ png_sPLT_tp np;
+ int i;
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ np = (png_sPLT_tp)png_malloc_warn(png_ptr,
+ (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
+ if (np == NULL)
+ {
+ png_warning(png_ptr, "No memory for sPLT palettes.");
+ return;
+ }
+
+ png_memcpy(np, info_ptr->splt_palettes,
+ info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes=NULL;
+
+ for (i = 0; i < nentries; i++)
+ {
+ png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
+ png_sPLT_tp from = entries + i;
+
+ to->name = (png_charp)png_malloc_warn(png_ptr,
+ png_strlen(from->name) + 1);
+ if (to->name == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing sPLT chunk");
+ }
+ /* TODO: use png_malloc_warn */
+ png_strncpy(to->name, from->name, png_strlen(from->name));
+ to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
+ from->nentries * png_sizeof(png_sPLT_entry));
+ /* TODO: use png_malloc_warn */
+ png_memcpy(to->entries, from->entries,
+ from->nentries * png_sizeof(png_sPLT_entry));
+ if (to->entries == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing sPLT chunk");
+ png_free(png_ptr,to->name);
+ to->name = NULL;
+ }
+ to->nentries = from->nentries;
+ to->depth = from->depth;
+ }
+
+ info_ptr->splt_palettes = np;
+ info_ptr->splt_palettes_num += nentries;
+ info_ptr->valid |= PNG_INFO_sPLT;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_SPLT;
+#endif
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#if defined(PNG_APNG_SUPPORTED)
+png_uint_32 PNGAPI
+png_set_acTL(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 num_frames, png_uint_32 num_plays)
+{
+ png_debug1(1, "in %s storage function\n", "acTL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ {
+ png_warning(png_ptr,
+ "Call to png_set_acTL() with NULL png_ptr "
+ "or info_ptr ignored");
+ return (0);
+ }
+ if (num_frames == 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set acTL with num_frames zero");
+ return (0);
+ }
+ if (num_frames > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set acTL with num_frames > 2^31-1");
+ return (0);
+ }
+ if (num_plays > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set acTL with num_plays "
+ "> 2^31-1");
+ return (0);
+ }
+
+ info_ptr->num_frames = num_frames;
+ info_ptr->num_plays = num_plays;
+
+ info_ptr->valid |= PNG_INFO_acTL;
+
+ return (1);
+}
+
+/* delay_num and delay_den can hold any values including zero */
+png_uint_32 PNGAPI
+png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den,
+ png_byte dispose_op, png_byte blend_op)
+{
+ png_debug1(1, "in %s storage function\n", "fcTL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ {
+ png_warning(png_ptr,
+ "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
+ "ignored");
+ return (0);
+ }
+
+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
+ delay_num, delay_den, dispose_op, blend_op);
+
+ info_ptr->next_frame_width = width;
+ info_ptr->next_frame_height = height;
+ info_ptr->next_frame_x_offset = x_offset;
+ info_ptr->next_frame_y_offset = y_offset;
+ info_ptr->next_frame_delay_num = delay_num;
+ info_ptr->next_frame_delay_den = delay_den;
+ info_ptr->next_frame_dispose_op = dispose_op;
+ info_ptr->next_frame_blend_op = blend_op;
+
+ info_ptr->valid |= PNG_INFO_fcTL;
+
+ return (1);
+}
+
+void /* PRIVATE */
+png_ensure_fcTL_is_valid(png_structp png_ptr,
+ png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den,
+ png_byte dispose_op, png_byte blend_op)
+{
+ if (width + x_offset > png_ptr->first_frame_width ||
+ height + y_offset > png_ptr->first_frame_height)
+ png_error(png_ptr, "dimensions of a frame are greater than"
+ "the ones in IHDR");
+ if (width > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
+ if (height > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
+ if (x_offset > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
+ if (y_offset > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
+
+ if (dispose_op != PNG_DISPOSE_OP_NONE &&
+ dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
+ dispose_op != PNG_DISPOSE_OP_PREVIOUS)
+ png_error(png_ptr, "invalid dispose_op in fcTL");
+
+ if (blend_op != PNG_BLEND_OP_SOURCE &&
+ blend_op != PNG_BLEND_OP_OVER)
+ png_error(png_ptr, "invalid blend_op in fcTL");
+
+ if (blend_op == PNG_BLEND_OP_OVER) {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for "
+ "color type 'greyscale without alpha'");
+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) &&
+ !(png_ptr->color_type & PNG_COLOR_MASK_ALPHA))
+ png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for "
+ "color type 'truecolor without alpha'");
+ }
+}
+
+png_uint_32 PNGAPI
+png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
+ png_byte is_hidden)
+{
+ png_debug(1, "in png_first_frame_is_hidden()\n");
+
+ if (png_ptr == NULL)
+ return 0;
+
+ if(is_hidden)
+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
+ else
+ png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
+
+ return 1;
+}
+#endif /* PNG_APNG_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_unknown_chunks(png_structp png_ptr,
+ png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
+{
+ png_unknown_chunkp np;
+ int i;
+
+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
+ return;
+
+ np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
+ (info_ptr->unknown_chunks_num + num_unknowns) *
+ png_sizeof(png_unknown_chunk));
+ if (np == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing unknown chunk.");
+ return;
+ }
+
+ png_memcpy(np, info_ptr->unknown_chunks,
+ info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks=NULL;
+
+ for (i = 0; i < num_unknowns; i++)
+ {
+ png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
+ png_unknown_chunkp from = unknowns + i;
+
+ png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
+ to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
+ if (to->data == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing unknown chunk.");
+ }
+ else
+ {
+ png_memcpy(to->data, from->data, from->size);
+ to->size = from->size;
+
+ /* note our location in the read or write sequence */
+ to->location = (png_byte)(png_ptr->mode & 0xff);
+ }
+ }
+
+ info_ptr->unknown_chunks = np;
+ info_ptr->unknown_chunks_num += num_unknowns;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_UNKN;
+#endif
+}
+void PNGAPI
+png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
+ int chunk, int location)
+{
+ if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
+ (int)info_ptr->unknown_chunks_num)
+ info_ptr->unknown_chunks[chunk].location = (png_byte)location;
+}
+#endif
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+void PNGAPI
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+ /* This function is deprecated in favor of png_permit_mng_features()
+ and will be removed from libpng-1.3.0 */
+ png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->mng_features_permitted = (png_byte)
+ ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
+ ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
+}
+#endif
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+{
+ png_debug(1, "in png_permit_mng_features\n");
+ if (png_ptr == NULL)
+ return (png_uint_32)0;
+ png_ptr->mng_features_permitted =
+ (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
+ return (png_uint_32)png_ptr->mng_features_permitted;
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
+ chunk_list, int num_chunks)
+{
+ png_bytep new_list, p;
+ int i, old_num_chunks;
+ if (png_ptr == NULL)
+ return;
+ if (num_chunks == 0)
+ {
+ if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
+ png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+ else
+ png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+
+ if(keep == PNG_HANDLE_CHUNK_ALWAYS)
+ png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+ else
+ png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+ return;
+ }
+ if (chunk_list == NULL)
+ return;
+ old_num_chunks=png_ptr->num_chunk_list;
+ new_list=(png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(5*(num_chunks+old_num_chunks)));
+ if(png_ptr->chunk_list != NULL)
+ {
+ png_memcpy(new_list, png_ptr->chunk_list,
+ (png_size_t)(5*old_num_chunks));
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ }
+ png_memcpy(new_list+5*old_num_chunks, chunk_list,
+ (png_size_t)(5*num_chunks));
+ for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
+ *p=(png_byte)keep;
+ png_ptr->num_chunk_list=old_num_chunks+num_chunks;
+ png_ptr->chunk_list=new_list;
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_ptr->free_me |= PNG_FREE_LIST;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
+ png_user_chunk_ptr read_user_chunk_fn)
+{
+ png_debug(1, "in png_set_read_user_chunk_fn\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+ png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
+{
+ png_debug1(1, "in %s storage function\n", "rows");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+ info_ptr->row_pointers = row_pointers;
+ if(row_pointers)
+ info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+void PNGAPI
+png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
+{
+ if (png_ptr == NULL)
+ return;
+ if(png_ptr->zbuf)
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf_size = (png_size_t)size;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+}
+#endif
+
+void PNGAPI
+png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
+{
+ if (png_ptr && info_ptr)
+ info_ptr->valid &= ~(mask);
+}
+
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* function was added to libpng 1.2.0 and should always exist by default */
+void PNGAPI
+png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
+{
+/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
+ if (png_ptr != NULL)
+ png_ptr->asm_flags = 0;
+}
+
+/* this function was added to libpng 1.2.0 */
+void PNGAPI
+png_set_mmx_thresholds (png_structp png_ptr,
+ png_byte mmx_bitdepth_threshold,
+ png_uint_32 mmx_rowbytes_threshold)
+{
+/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
+ if (png_ptr == NULL)
+ return;
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* this function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
+ png_uint_32 user_height_max)
+{
+ /* Images with dimensions larger than these limits will be
+ * rejected by png_set_IHDR(). To accept any PNG datastream
+ * regardless of dimensions, set both limits to 0x7ffffffL.
+ */
+ if(png_ptr == NULL) return;
+ png_ptr->user_width_max = user_width_max;
+ png_ptr->user_height_max = user_height_max;
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+#endif /* ?PNG_1_0_X */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngtest.c b/kernel/kls_png/ksquirrel-libs-png/pngtest.c
new file mode 100644
index 0000000..3981a49
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngtest.c
@@ -0,0 +1,1551 @@
+
+/* pngtest.c - a simple test program to test libpng
+ *
+ * Last changed in libpng 1.2.6 - August 15, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2004 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This program reads in a PNG image, writes it out again, and then
+ * compares the two files. If the files are identical, this shows that
+ * the basic chunk handling, filtering, and (de)compression code is working
+ * properly. It does not currently test all of the transforms, although
+ * it probably should.
+ *
+ * The program will report "FAIL" in certain legitimate cases:
+ * 1) when the compression level or filter selection method is changed.
+ * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
+ * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
+ * exist in the input file.
+ * 4) others not listed here...
+ * In these cases, it is best to check with another tool such as "pngcheck"
+ * to see what the differences between the two files are.
+ *
+ * If a filename is given on the command-line, then this file is used
+ * for the input, rather than the default "pngtest.png". This allows
+ * testing a wide variety of files easily. You can also test a number
+ * of files at once by typing "pngtest -m file1.png file2.png ..."
+ */
+
+#include "png.h"
+
+#if defined(_WIN32_WCE)
+# if _WIN32_WCE < 211
+ __error__ (f|w)printf functions are not supported on old WindowsCE.;
+# endif
+# include <windows.h>
+# include <stdlib.h>
+# define READFILE(file, data, length, check) \
+ if (ReadFile(file, data, length, &check,NULL)) check = 0
+# define WRITEFILE(file, data, length, check)) \
+ if (WriteFile(file, data, length, &check, NULL)) check = 0
+# define FCLOSE(file) CloseHandle(file)
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# define READFILE(file, data, length, check) \
+ check=(png_size_t)fread(data,(png_size_t)1,length,file)
+# define WRITEFILE(file, data, length, check) \
+ check=(png_size_t)fwrite(data,(png_size_t)1, length, file)
+# define FCLOSE(file) fclose(file)
+#endif
+
+#if defined(PNG_NO_STDIO)
+# if defined(_WIN32_WCE)
+ typedef HANDLE png_FILE_p;
+# else
+ typedef FILE * png_FILE_p;
+# endif
+#endif
+
+/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
+#ifndef PNG_DEBUG
+# define PNG_DEBUG 0
+#endif
+
+#if !PNG_DEBUG
+# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
+#endif
+
+/* Turn on CPU timing
+#define PNGTEST_TIMING
+*/
+
+#ifdef PNG_NO_FLOATING_POINT_SUPPORTED
+#undef PNGTEST_TIMING
+#endif
+
+#ifdef PNGTEST_TIMING
+static float t_start, t_stop, t_decode, t_encode, t_misc;
+#include <time.h>
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+static int tIME_chunk_present=0;
+static char tIME_string[30] = "no tIME chunk present in file";
+#endif
+
+static int verbose = 0;
+
+int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
+
+#ifdef __TURBOC__
+#include <mem.h>
+#endif
+
+/* defined so I can write to a file on gui/windowing platforms */
+/* #define STDERR stderr */
+#define STDERR stdout /* for DOS */
+
+/* example of using row callbacks to make a simple progress meter */
+static int status_pass=1;
+static int status_dots_requested=0;
+static int status_dots=1;
+
+/* In case a system header (e.g., on AIX) defined jmpbuf */
+#ifdef jmpbuf
+# undef jmpbuf
+#endif
+
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
+#endif
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+ if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return;
+ if(status_pass != pass)
+ {
+ fprintf(stdout,"\n Pass %d: ",pass);
+ status_pass = pass;
+ status_dots = 31;
+ }
+ status_dots--;
+ if(status_dots == 0)
+ {
+ fprintf(stdout, "\n ");
+ status_dots=30;
+ }
+ fprintf(stdout, "r");
+}
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+ if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return;
+ fprintf(stdout, "w");
+}
+
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+/* Example of using user transform callback (we don't transform anything,
+ but merely examine the row filters. We set this to 256 rather than
+ 5 in case illegal filter values are present.) */
+static png_uint_32 filters_used[256];
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+ if(png_ptr != NULL && row_info != NULL)
+ ++filters_used[*(data-1)];
+}
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+/* example of using user transform callback (we don't transform anything,
+ but merely count the zero samples) */
+
+static png_uint_32 zero_samples;
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+ png_bytep dp = data;
+ if(png_ptr == NULL)return;
+
+ /* contents of row_info:
+ * png_uint_32 width width of row
+ * png_uint_32 rowbytes number of bytes in row
+ * png_byte color_type color type of pixels
+ * png_byte bit_depth bit depth of samples
+ * png_byte channels number of channels (1-4)
+ * png_byte pixel_depth bits per pixel (depth*channels)
+ */
+
+
+ /* counts the number of zero samples (or zero pixels if color_type is 3 */
+
+ if(row_info->color_type == 0 || row_info->color_type == 3)
+ {
+ int pos=0;
+ png_uint_32 n, nstop;
+ for (n=0, nstop=row_info->width; n<nstop; n++)
+ {
+ if(row_info->bit_depth == 1)
+ {
+ if(((*dp << pos++ ) & 0x80) == 0) zero_samples++;
+ if(pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+ if(row_info->bit_depth == 2)
+ {
+ if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++;
+ if(pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+ if(row_info->bit_depth == 4)
+ {
+ if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++;
+ if(pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+ if(row_info->bit_depth == 8)
+ if(*dp++ == 0) zero_samples++;
+ if(row_info->bit_depth == 16)
+ {
+ if((*dp | *(dp+1)) == 0) zero_samples++;
+ dp+=2;
+ }
+ }
+ }
+ else /* other color types */
+ {
+ png_uint_32 n, nstop;
+ int channel;
+ int color_channels = row_info->channels;
+ if(row_info->color_type > 3)color_channels--;
+
+ for (n=0, nstop=row_info->width; n<nstop; n++)
+ {
+ for (channel = 0; channel < color_channels; channel++)
+ {
+ if(row_info->bit_depth == 8)
+ if(*dp++ == 0) zero_samples++;
+ if(row_info->bit_depth == 16)
+ {
+ if((*dp | *(dp+1)) == 0) zero_samples++;
+ dp+=2;
+ }
+ }
+ if(row_info->color_type > 3)
+ {
+ dp++;
+ if(row_info->bit_depth == 16)dp++;
+ }
+ }
+ }
+}
+#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+
+static int wrote_question = 0;
+
+#if defined(PNG_NO_STDIO)
+/* START of code to validate stdio-free compilation */
+/* These copies of the default read/write functions come from pngrio.c and */
+/* pngwio.c. They allow "don't include stdio" testing of the library. */
+/* This is the function that does the actual reading of data. If you are
+ not reading from a standard C stream, you should create a replacement
+ read_data function and use it at run time with png_set_read_fn(), rather
+ than changing the library. */
+
+#ifndef USE_FAR_KEYWORD
+static void
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+ READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
+
+ if (check != length)
+ {
+ png_error(png_ptr, "Read Error!");
+ }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ int check;
+ png_byte *n_data;
+ png_FILE_p io_ptr;
+
+ /* Check if data really is near. If so, use usual code. */
+ n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)n_data == data)
+ {
+ READFILE(io_ptr, n_data, length, check);
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t read, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ read = MIN(NEAR_BUF_SIZE, remaining);
+ READFILE(io_ptr, buf, 1, err);
+ png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+ if(err != read)
+ break;
+ else
+ check += err;
+ data += read;
+ remaining -= read;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ {
+ png_error(png_ptr, "read Error");
+ }
+}
+#endif /* USE_FAR_KEYWORD */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+static void
+pngtest_flush(png_structp png_ptr)
+{
+#if !defined(_WIN32_WCE)
+ png_FILE_p io_ptr;
+ io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+ if (io_ptr != NULL)
+ fflush(io_ptr);
+#endif
+}
+#endif
+
+/* This is the function that does the actual writing of data. If you are
+ not writing to a standard C stream, you should create a replacement
+ write_data function and use it at run time with png_set_write_fn(), rather
+ than changing the library. */
+#ifndef USE_FAR_KEYWORD
+static void
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+
+ WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
+ if (check != length)
+ {
+ png_error(png_ptr, "Write Error");
+ }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+ png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
+ png_FILE_p io_ptr;
+
+ /* Check if data really is near. If so, use usual code. */
+ near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)near_data == data)
+ {
+ WRITEFILE(io_ptr, near_data, length, check);
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t written, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ written = MIN(NEAR_BUF_SIZE, remaining);
+ png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+ WRITEFILE(io_ptr, buf, written, err);
+ if (err != written)
+ break;
+ else
+ check += err;
+ data += written;
+ remaining -= written;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ {
+ png_error(png_ptr, "Write Error");
+ }
+}
+#endif /* USE_FAR_KEYWORD */
+#endif /* PNG_NO_STDIO */
+/* END of code to validate stdio-free compilation */
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void
+pngtest_warning(png_structp png_ptr, png_const_charp message)
+{
+ PNG_CONST char *name = "UNKNOWN (ERROR!)";
+ if (png_ptr != NULL && png_ptr->error_ptr != NULL)
+ name = png_ptr->error_ptr;
+ fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+}
+
+/* This is the default error handling function. Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void
+pngtest_error(png_structp png_ptr, png_const_charp message)
+{
+ pngtest_warning(png_ptr, message);
+ /* We can return because png_error calls the default handler, which is
+ * actually OK in this case. */
+}
+
+/* START of code to validate memory allocation and deallocation */
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+
+/* Allocate memory. For reasonable files, size should never exceed
+ 64K. However, zlib may allocate more then 64K if you don't tell
+ it not to. See zconf.h and png.h for more information. zlib does
+ need to allocate exactly 64K, so whatever you call here must
+ have the ability to do that.
+
+ This piece of code can be compiled to validate max 64K allocations
+ by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
+typedef struct memory_information
+{
+ png_uint_32 size;
+ png_voidp pointer;
+ struct memory_information FAR *next;
+} memory_information;
+typedef memory_information FAR *memory_infop;
+
+static memory_infop pinformation = NULL;
+static int current_allocation = 0;
+static int maximum_allocation = 0;
+static int total_allocation = 0;
+static int num_allocations = 0;
+
+png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
+void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
+
+png_voidp
+png_debug_malloc(png_structp png_ptr, png_uint_32 size)
+{
+
+ /* png_malloc has already tested for NULL; png_create_struct calls
+ png_debug_malloc directly, with png_ptr == NULL which is OK */
+
+ if (size == 0)
+ return (NULL);
+
+ /* This calls the library allocator twice, once to get the requested
+ buffer and once to get a new free list entry. */
+ {
+ /* Disable malloc_fn and free_fn */
+ memory_infop pinfo;
+ png_set_mem_fn(png_ptr, NULL, NULL, NULL);
+ pinfo = (memory_infop)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof (*pinfo));
+ pinfo->size = size;
+ current_allocation += size;
+ total_allocation += size;
+ num_allocations ++;
+ if (current_allocation > maximum_allocation)
+ maximum_allocation = current_allocation;
+ pinfo->pointer = (png_voidp)png_malloc(png_ptr, size);
+ /* Restore malloc_fn and free_fn */
+ png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
+ (png_free_ptr)png_debug_free);
+ if (size != 0 && pinfo->pointer == NULL)
+ {
+ current_allocation -= size;
+ total_allocation -= size;
+ png_error(png_ptr,
+ "out of memory in pngtest->png_debug_malloc.");
+ }
+ pinfo->next = pinformation;
+ pinformation = pinfo;
+ /* Make sure the caller isn't assuming zeroed memory. */
+ png_memset(pinfo->pointer, 0xdd, pinfo->size);
+ if(verbose)
+ printf("png_malloc %lu bytes at %x\n",(unsigned long)size,
+ pinfo->pointer);
+ return (png_voidp)(pinfo->pointer);
+ }
+}
+
+/* Free a pointer. It is removed from the list at the same time. */
+void
+png_debug_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL)
+ fprintf(STDERR, "NULL pointer to png_debug_free.\n");
+ if (ptr == 0)
+ {
+#if 0 /* This happens all the time. */
+ fprintf(STDERR, "WARNING: freeing NULL pointer\n");
+#endif
+ return;
+ }
+
+ /* Unlink the element from the list. */
+ {
+ memory_infop FAR *ppinfo = &pinformation;
+ for (;;)
+ {
+ memory_infop pinfo = *ppinfo;
+ if (pinfo->pointer == ptr)
+ {
+ *ppinfo = pinfo->next;
+ current_allocation -= pinfo->size;
+ if (current_allocation < 0)
+ fprintf(STDERR, "Duplicate free of memory\n");
+ /* We must free the list element too, but first kill
+ the memory that is to be freed. */
+ png_memset(ptr, 0x55, pinfo->size);
+ png_free_default(png_ptr, pinfo);
+ pinfo=NULL;
+ break;
+ }
+ if (pinfo->next == NULL)
+ {
+ fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
+ break;
+ }
+ ppinfo = &pinfo->next;
+ }
+ }
+
+ /* Finally free the data. */
+ if(verbose)
+ printf("Freeing %x\n",ptr);
+ png_free_default(png_ptr, ptr);
+ ptr=NULL;
+}
+#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
+/* END of code to test memory allocation/deallocation */
+
+/* Test one file */
+int
+test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
+{
+ static png_FILE_p fpin;
+ static png_FILE_p fpout; /* "static" prevents setjmp corruption */
+ png_structp read_ptr;
+ png_infop read_info_ptr, end_info_ptr;
+#ifdef PNG_WRITE_SUPPORTED
+ png_structp write_ptr;
+ png_infop write_info_ptr;
+ png_infop write_end_info_ptr;
+#else
+ png_structp write_ptr = NULL;
+ png_infop write_info_ptr = NULL;
+ png_infop write_end_info_ptr = NULL;
+#endif
+ png_bytep row_buf;
+ png_uint_32 y;
+ png_uint_32 width, height;
+ int num_pass, pass;
+ int bit_depth, color_type;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+
+#if defined(_WIN32_WCE)
+ TCHAR path[MAX_PATH];
+#endif
+ char inbuf[256], outbuf[256];
+
+ row_buf = NULL;
+
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
+ if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpin = fopen(inname, "rb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not find input file %s\n", inname);
+ return (1);
+ }
+
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
+ if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpout = fopen(outname, "wb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not open output file %s\n", outname);
+ FCLOSE(fpin);
+ return (1);
+ }
+
+ png_debug(0, "Allocating read and write structures\n");
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
+ (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
+#else
+ read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL);
+#endif
+ png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
+ pngtest_warning);
+#ifdef PNG_WRITE_SUPPORTED
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
+ (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
+#else
+ write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL);
+#endif
+ png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
+ pngtest_warning);
+#endif
+ png_debug(0, "Allocating read_info, write_info and end_info structures\n");
+ read_info_ptr = png_create_info_struct(read_ptr);
+ end_info_ptr = png_create_info_struct(read_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ write_info_ptr = png_create_info_struct(write_ptr);
+ write_end_info_ptr = png_create_info_struct(write_ptr);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_debug(0, "Setting jmpbuf for read struct\n");
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_jmpbuf(read_ptr)))
+#endif
+ {
+ fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
+ if (row_buf)
+ png_free(read_ptr, row_buf);
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+ png_debug(0, "Setting jmpbuf for write struct\n");
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_jmpbuf(write_ptr)))
+#endif
+ {
+ fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf));
+#endif
+#endif
+#endif
+
+ png_debug(0, "Initializing input and output streams\n");
+#if !defined(PNG_NO_STDIO)
+ png_init_io(read_ptr, fpin);
+# ifdef PNG_WRITE_SUPPORTED
+ png_init_io(write_ptr, fpout);
+# endif
+#else
+ png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
+# ifdef PNG_WRITE_SUPPORTED
+ png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
+# if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ pngtest_flush);
+# else
+ NULL);
+# endif
+# endif
+#endif
+ if(status_dots_requested == 1)
+ {
+#ifdef PNG_WRITE_SUPPORTED
+ png_set_write_status_fn(write_ptr, write_row_callback);
+#endif
+ png_set_read_status_fn(read_ptr, read_row_callback);
+ }
+ else
+ {
+#ifdef PNG_WRITE_SUPPORTED
+ png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
+#endif
+ png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
+ }
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ {
+ int i;
+ for(i=0; i<256; i++)
+ filters_used[i]=0;
+ png_set_read_user_transform_fn(read_ptr, count_filters);
+ }
+#endif
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ zero_samples=0;
+ png_set_write_user_transform_fn(write_ptr, count_zero_samples);
+#endif
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+# ifndef PNG_HANDLE_CHUNK_ALWAYS
+# define PNG_HANDLE_CHUNK_ALWAYS 3
+# endif
+ png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
+ png_bytep_NULL, 0);
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+# ifndef PNG_HANDLE_CHUNK_IF_SAFE
+# define PNG_HANDLE_CHUNK_IF_SAFE 2
+# endif
+ png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
+ png_bytep_NULL, 0);
+#endif
+
+ png_debug(0, "Reading info struct\n");
+ png_read_info(read_ptr, read_info_ptr);
+
+ png_debug(0, "Transferring info struct\n");
+ {
+ int interlace_type, compression_type, filter_type;
+
+ if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
+ &color_type, &interlace_type, &compression_type, &filter_type))
+ {
+ png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ color_type, interlace_type, compression_type, filter_type);
+#else
+ color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
+#endif
+ }
+ }
+#if defined(PNG_FIXED_POINT_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
+ {
+ png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+ blue_y;
+ if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+ &red_y, &green_x, &green_y, &blue_x, &blue_y))
+ {
+ png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
+ red_y, green_x, green_y, blue_x, blue_y);
+ }
+ }
+#endif
+#if defined(PNG_gAMA_SUPPORTED)
+ {
+ png_fixed_point gamma;
+
+ if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
+ {
+ png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
+ }
+ }
+#endif
+#else /* Use floating point versions */
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
+ {
+ double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+ blue_y;
+ if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+ &red_y, &green_x, &green_y, &blue_x, &blue_y))
+ {
+ png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
+ red_y, green_x, green_y, blue_x, blue_y);
+ }
+ }
+#endif
+#if defined(PNG_gAMA_SUPPORTED)
+ {
+ double gamma;
+
+ if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
+ {
+ png_set_gAMA(write_ptr, write_info_ptr, gamma);
+ }
+ }
+#endif
+#endif /* floating point */
+#endif /* fixed point */
+#if defined(PNG_iCCP_SUPPORTED)
+ {
+ png_charp name;
+ png_charp profile;
+ png_uint_32 proflen;
+ int compression_type;
+
+ if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
+ &profile, &proflen))
+ {
+ png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
+ profile, proflen);
+ }
+ }
+#endif
+#if defined(PNG_sRGB_SUPPORTED)
+ {
+ int intent;
+
+ if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
+ {
+ png_set_sRGB(write_ptr, write_info_ptr, intent);
+ }
+ }
+#endif
+ {
+ png_colorp palette;
+ int num_palette;
+
+ if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
+ {
+ png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
+ }
+ }
+#if defined(PNG_bKGD_SUPPORTED)
+ {
+ png_color_16p background;
+
+ if (png_get_bKGD(read_ptr, read_info_ptr, &background))
+ {
+ png_set_bKGD(write_ptr, write_info_ptr, background);
+ }
+ }
+#endif
+#if defined(PNG_hIST_SUPPORTED)
+ {
+ png_uint_16p hist;
+
+ if (png_get_hIST(read_ptr, read_info_ptr, &hist))
+ {
+ png_set_hIST(write_ptr, write_info_ptr, hist);
+ }
+ }
+#endif
+#if defined(PNG_oFFs_SUPPORTED)
+ {
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
+ {
+ png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
+ }
+ }
+#endif
+#if defined(PNG_pCAL_SUPPORTED)
+ {
+ png_charp purpose, units;
+ png_charpp params;
+ png_int_32 X0, X1;
+ int type, nparams;
+
+ if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
+ &nparams, &units, &params))
+ {
+ png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
+ nparams, units, params);
+ }
+ }
+#endif
+#if defined(PNG_pHYs_SUPPORTED)
+ {
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
+ {
+ png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
+ }
+ }
+#endif
+#if defined(PNG_sBIT_SUPPORTED)
+ {
+ png_color_8p sig_bit;
+
+ if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
+ {
+ png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
+ }
+ }
+#endif
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ {
+ int unit;
+ double scal_width, scal_height;
+
+ if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
+ &scal_height))
+ {
+ png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+ }
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ {
+ int unit;
+ png_charp scal_width, scal_height;
+
+ if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
+ &scal_height))
+ {
+ png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+ }
+ }
+#endif
+#endif
+#endif
+#if defined(PNG_TEXT_SUPPORTED)
+ {
+ png_textp text_ptr;
+ int num_text;
+
+ if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
+ {
+ png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
+ png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
+ }
+ }
+#endif
+#if defined(PNG_tIME_SUPPORTED)
+ {
+ png_timep mod_time;
+
+ if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
+ {
+ png_set_tIME(write_ptr, write_info_ptr, mod_time);
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ /* we have to use png_strncpy instead of "=" because the string
+ pointed to by png_convert_to_rfc1123() gets free'ed before
+ we use it */
+ png_strncpy(tIME_string,png_convert_to_rfc1123(read_ptr,
+ mod_time),30);
+ tIME_chunk_present++;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ }
+#endif
+#if defined(PNG_tRNS_SUPPORTED)
+ {
+ png_bytep trans;
+ int num_trans;
+ png_color_16p trans_values;
+
+ if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
+ &trans_values))
+ {
+ png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
+ trans_values);
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ {
+ png_unknown_chunkp unknowns;
+ int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
+ &unknowns);
+ if (num_unknowns)
+ {
+ png_size_t i;
+ png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
+ num_unknowns);
+ /* copy the locations from the read_info_ptr. The automatically
+ generated locations in write_info_ptr are wrong because we
+ haven't written anything yet */
+ for (i = 0; i < (png_size_t)num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
+ unknowns[i].location);
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+ png_debug(0, "\nWriting info struct\n");
+
+/* If we wanted, we could write info in two steps:
+ png_write_info_before_PLTE(write_ptr, write_info_ptr);
+ */
+ png_write_info(write_ptr, write_info_ptr);
+#endif
+
+#ifdef SINGLE_ROWBUF_ALLOC
+ png_debug(0, "\nAllocating row buffer...");
+ row_buf = (png_bytep)png_malloc(read_ptr,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+ png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf);
+#endif /* SINGLE_ROWBUF_ALLOC */
+ png_debug(0, "Writing row data\n");
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ num_pass = png_set_interlace_handling(read_ptr);
+# ifdef PNG_WRITE_SUPPORTED
+ png_set_interlace_handling(write_ptr);
+# endif
+#else
+ num_pass=1;
+#endif
+
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ png_debug1(0, "Writing row data for pass %d\n",pass);
+ for (y = 0; y < height; y++)
+ {
+#ifndef SINGLE_ROWBUF_ALLOC
+ png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y);
+ row_buf = (png_bytep)png_malloc(read_ptr,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+ png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+#endif /* !SINGLE_ROWBUF_ALLOC */
+ png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_decode += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+ png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_encode += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef SINGLE_ROWBUF_ALLOC
+ png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y);
+ png_free(read_ptr, row_buf);
+#endif /* !SINGLE_ROWBUF_ALLOC */
+ }
+ }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+
+ png_debug(0, "Reading and writing end_info data\n");
+
+ png_read_end(read_ptr, end_info_ptr);
+#if defined(PNG_TEXT_SUPPORTED)
+ {
+ png_textp text_ptr;
+ int num_text;
+
+ if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
+ {
+ png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
+ png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
+ }
+ }
+#endif
+#if defined(PNG_tIME_SUPPORTED)
+ {
+ png_timep mod_time;
+
+ if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
+ {
+ png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ /* we have to use png_strncpy instead of "=" because the string
+ pointed to by png_convert_to_rfc1123() gets free'ed before
+ we use it */
+ png_strncpy(tIME_string,png_convert_to_rfc1123(read_ptr,
+ mod_time),30);
+ tIME_chunk_present++;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ {
+ png_unknown_chunkp unknowns;
+ int num_unknowns;
+ num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
+ &unknowns);
+ if (num_unknowns)
+ {
+ png_size_t i;
+ png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
+ num_unknowns);
+ /* copy the locations from the read_info_ptr. The automatically
+ generated locations in write_end_info_ptr are wrong because we
+ haven't written the end_info yet */
+ for (i = 0; i < (png_size_t)num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
+ unknowns[i].location);
+ }
+ }
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+ png_write_end(write_ptr, write_end_info_ptr);
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+ if(verbose)
+ {
+ png_uint_32 iwidth, iheight;
+ iwidth = png_get_image_width(write_ptr, write_info_ptr);
+ iheight = png_get_image_height(write_ptr, write_info_ptr);
+ fprintf(STDERR, "Image width = %lu, height = %lu\n",
+ (unsigned long)iwidth, (unsigned long)iheight);
+ }
+#endif
+
+ png_debug(0, "Destroying data structs\n");
+#ifdef SINGLE_ROWBUF_ALLOC
+ png_debug(1, "destroying row_buf for read_ptr\n");
+ png_free(read_ptr, row_buf);
+ row_buf=NULL;
+#endif /* SINGLE_ROWBUF_ALLOC */
+ png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n");
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ png_debug(1, "destroying write_end_info_ptr\n");
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ png_debug(1, "destroying write_ptr, write_info_ptr\n");
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ png_debug(0, "Destruction complete.\n");
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ png_debug(0, "Opening files for comparison\n");
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
+ if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpin = fopen(inname, "rb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not find file %s\n", inname);
+ return (1);
+ }
+
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
+ if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpout = fopen(outname, "rb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not find file %s\n", outname);
+ FCLOSE(fpin);
+ return (1);
+ }
+
+ for(;;)
+ {
+ png_size_t num_in, num_out;
+
+ READFILE(fpin, inbuf, 1, num_in);
+ READFILE(fpout, outbuf, 1, num_out);
+
+ if (num_in != num_out)
+ {
+ fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
+ inname, outname);
+ if(wrote_question == 0)
+ {
+ fprintf(STDERR,
+ " Was %s written with the same maximum IDAT chunk size (%d bytes),",
+ inname,PNG_ZBUF_SIZE);
+ fprintf(STDERR,
+ "\n filtering heuristic (libpng default), compression");
+ fprintf(STDERR,
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
+ wrote_question=1;
+ }
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (0);
+ }
+
+ if (!num_in)
+ break;
+
+ if (png_memcmp(inbuf, outbuf, num_in))
+ {
+ fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
+ if(wrote_question == 0)
+ {
+ fprintf(STDERR,
+ " Was %s written with the same maximum IDAT chunk size (%d bytes),",
+ inname,PNG_ZBUF_SIZE);
+ fprintf(STDERR,
+ "\n filtering heuristic (libpng default), compression");
+ fprintf(STDERR,
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
+ wrote_question=1;
+ }
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (0);
+ }
+ }
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ return (0);
+}
+
+/* input and output filenames */
+#ifdef RISCOS
+static PNG_CONST char *inname = "pngtest/png";
+static PNG_CONST char *outname = "pngout/png";
+#else
+static PNG_CONST char *inname = "pngtest.png";
+static PNG_CONST char *outname = "pngout.png";
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int multiple = 0;
+ int ierror = 0;
+
+ fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
+ fprintf(STDERR,"%s",png_get_copyright(NULL));
+ /* Show the version of libpng used in building the library */
+ fprintf(STDERR," library (%lu):%s",
+ (unsigned long)png_access_version_number(),
+ png_get_header_version(NULL));
+ /* Show the version of libpng used in building the application */
+ fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
+ PNG_HEADER_VERSION_STRING);
+ fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n",
+ (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
+
+ /* Do some consistency checking on the memory allocation settings, I'm
+ not sure this matters, but it is nice to know, the first of these
+ tests should be impossible because of the way the macros are set
+ in pngconf.h */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+ fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
+#endif
+ /* I think the following can happen. */
+#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
+ fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
+#endif
+
+ if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
+ {
+ fprintf(STDERR,
+ "Warning: versions are different between png.h and png.c\n");
+ fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
+ ++ierror;
+ }
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "-m") == 0)
+ {
+ multiple = 1;
+ status_dots_requested = 0;
+ }
+ else if (strcmp(argv[1], "-mv") == 0 ||
+ strcmp(argv[1], "-vm") == 0 )
+ {
+ multiple = 1;
+ verbose = 1;
+ status_dots_requested = 1;
+ }
+ else if (strcmp(argv[1], "-v") == 0)
+ {
+ verbose = 1;
+ status_dots_requested = 1;
+ inname = argv[2];
+ }
+ else
+ {
+ inname = argv[1];
+ status_dots_requested = 0;
+ }
+ }
+
+ if (!multiple && argc == 3+verbose)
+ outname = argv[2+verbose];
+
+ if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
+ {
+ fprintf(STDERR,
+ "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+ argv[0], argv[0]);
+ fprintf(STDERR,
+ " reads/writes one PNG file (without -m) or multiple files (-m)\n");
+ fprintf(STDERR,
+ " with -m %s is used as a temporary file\n", outname);
+ exit(1);
+ }
+
+ if (multiple)
+ {
+ int i;
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ int allocation_now = current_allocation;
+#endif
+ for (i=2; i<argc; ++i)
+ {
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ int k;
+#endif
+ int kerror;
+ fprintf(STDERR, "Testing %s:",argv[i]);
+ kerror = test_one_file(argv[i], outname);
+ if (kerror == 0)
+ {
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ fprintf(STDERR, "\n PASS (%lu zero samples)\n",
+ (unsigned long)zero_samples);
+#else
+ fprintf(STDERR, " PASS\n");
+#endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ for (k=0; k<256; k++)
+ if(filters_used[k])
+ fprintf(STDERR, " Filter %d was used %lu times\n",
+ k,(unsigned long)filters_used[k]);
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ if(tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n",tIME_string);
+ tIME_chunk_present = 0;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ else
+ {
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ if (allocation_now != current_allocation)
+ fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+ current_allocation-allocation_now);
+ if (current_allocation != 0)
+ {
+ memory_infop pinfo = pinformation;
+
+ fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+ current_allocation);
+ while (pinfo != NULL)
+ {
+ fprintf(STDERR, " %lu bytes at %x\n", (unsigned long)pinfo->size,
+ (unsigned int) pinfo->pointer);
+ pinfo = pinfo->next;
+ }
+ }
+#endif
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+ current_allocation);
+ fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+ maximum_allocation);
+ fprintf(STDERR, " Total memory allocation: %10d bytes\n",
+ total_allocation);
+ fprintf(STDERR, " Number of allocations: %10d\n",
+ num_allocations);
+#endif
+ }
+ else
+ {
+ int i;
+ for (i=0; i<3; ++i)
+ {
+ int kerror;
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ int allocation_now = current_allocation;
+#endif
+ if (i == 1) status_dots_requested = 1;
+ else if(verbose == 0)status_dots_requested = 0;
+ if (i == 0 || verbose == 1 || ierror != 0)
+ fprintf(STDERR, "Testing %s:",inname);
+ kerror = test_one_file(inname, outname);
+ if(kerror == 0)
+ {
+ if(verbose == 1 || i == 2)
+ {
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ int k;
+#endif
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ fprintf(STDERR, "\n PASS (%lu zero samples)\n",
+ (unsigned long)zero_samples);
+#else
+ fprintf(STDERR, " PASS\n");
+#endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ for (k=0; k<256; k++)
+ if(filters_used[k])
+ fprintf(STDERR, " Filter %d was used %lu times\n",
+ k,(unsigned long)filters_used[k]);
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ if(tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n",tIME_string);
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ }
+ else
+ {
+ if(verbose == 0 && i != 2)
+ fprintf(STDERR, "Testing %s:",inname);
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ if (allocation_now != current_allocation)
+ fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+ current_allocation-allocation_now);
+ if (current_allocation != 0)
+ {
+ memory_infop pinfo = pinformation;
+
+ fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+ current_allocation);
+ while (pinfo != NULL)
+ {
+ fprintf(STDERR," %lu bytes at %x\n",
+ (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
+ pinfo = pinfo->next;
+ }
+ }
+#endif
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+ current_allocation);
+ fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+ maximum_allocation);
+ fprintf(STDERR, " Total memory allocation: %10d bytes\n",
+ total_allocation);
+ fprintf(STDERR, " Number of allocations: %10d\n",
+ num_allocations);
+#endif
+ }
+
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+ fprintf(STDERR," CPU time used = %.3f seconds",
+ (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR," (decoding %.3f,\n",
+ t_decode/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR," encoding %.3f ,",
+ t_encode/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR," other %.3f seconds)\n\n",
+ t_misc/(float)CLOCKS_PER_SEC);
+#endif
+
+ if (ierror == 0)
+ fprintf(STDERR, "libpng passes test\n");
+ else
+ fprintf(STDERR, "libpng FAILS test\n");
+ return (int)(ierror != 0);
+}
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_20 your_png_h_is_not_version_1_2_20;
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngtrans.c b/kernel/kls_png/ksquirrel-libs-png/pngtrans.c
new file mode 100644
index 0000000..1640095
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngtrans.c
@@ -0,0 +1,662 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * Last changed in libpng 1.2.17 May 15, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_bgr\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_swap\n");
+ if(png_ptr == NULL) return;
+ if (png_ptr->bit_depth == 16)
+ png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_packing\n");
+ if(png_ptr == NULL) return;
+ if (png_ptr->bit_depth < 8)
+ {
+ png_ptr->transformations |= PNG_PACK;
+ png_ptr->usr_bit_depth = 8;
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_packswap\n");
+ if(png_ptr == NULL) return;
+ if (png_ptr->bit_depth < 8)
+ png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structp png_ptr, png_color_8p true_bits)
+{
+ png_debug(1, "in png_set_shift\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_SHIFT;
+ png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_interlace handling\n");
+ if (png_ptr && png_ptr->interlaced)
+ {
+ png_ptr->transformations |= PNG_INTERLACE;
+ return (7);
+ }
+
+ return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_filler\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_FILLER;
+ png_ptr->filler = (png_byte)filler;
+ if (filler_loc == PNG_FILLER_AFTER)
+ png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+ else
+ png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+
+ /* This should probably go in the "do_read_filler" routine.
+ * I attempted to do that in libpng-1.0.1a but that caused problems
+ * so I restored it in libpng-1.0.2a
+ */
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_ptr->usr_channels = 4;
+ }
+
+ /* Also I added this in libpng-1.0.2a (what happens when we expand
+ * a less-than-8-bit grayscale to GA? */
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
+ {
+ png_ptr->usr_channels = 2;
+ }
+}
+
+#if !defined(PNG_1_0_X)
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_add_alpha\n");
+ if(png_ptr == NULL) return;
+ png_set_filler(png_ptr, filler, filler_loc);
+ png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+#endif
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_swap_alpha\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_invert_alpha\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_invert_mono\n");
+ if(png_ptr == NULL) return;
+ png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_invert\n");
+ /* This test removed from libpng version 1.0.13 and 1.2.0:
+ * if (row_info->bit_depth == 1 &&
+ */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row == NULL || row_info == NULL)
+ return;
+#endif
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp++;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 8)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i+=2)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp+=2;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i+=4)
+ {
+ *rp = (png_byte)(~(*rp));
+ *(rp+1) = (png_byte)(~(*(rp+1)));
+ rp+=4;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_swap\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop= row_info->width * row_info->channels;
+
+ for (i = 0; i < istop; i++, rp += 2)
+ {
+ png_byte t = *rp;
+ *rp = *(rp + 1);
+ *(rp + 1) = t;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static PNG_CONST png_byte onebppswaptable[256] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static PNG_CONST png_byte twobppswaptable[256] = {
+ 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+ 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+ 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+ 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+ 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+ 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+ 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+ 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+ 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+ 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+ 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+ 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+ 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+ 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+ 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+ 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+ 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+ 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+ 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+ 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+ 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+ 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+ 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+ 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+ 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+ 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+ 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+ 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+ 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+ 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+ 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+ 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static PNG_CONST png_byte fourbppswaptable[256] = {
+ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+ 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+ 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+ 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+ 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+ 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+ 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+ 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+ 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+ 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+ 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+ 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+ 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+ 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+ 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+ 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+ 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+ 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+ 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+ 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+ 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+ 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+ 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+ 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+ 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+ 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+ 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+ 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+ 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+ 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_packswap\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->bit_depth < 8)
+ {
+ png_bytep rp, end, table;
+
+ end = row + row_info->rowbytes;
+
+ if (row_info->bit_depth == 1)
+ table = (png_bytep)onebppswaptable;
+ else if (row_info->bit_depth == 2)
+ table = (png_bytep)twobppswaptable;
+ else if (row_info->bit_depth == 4)
+ table = (png_bytep)fourbppswaptable;
+ else
+ return;
+
+ for (rp = row; rp < end; rp++)
+ *rp = table[*rp];
+ }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* remove filler or alpha byte(s) */
+void /* PRIVATE */
+png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
+{
+ png_debug(1, "in png_do_strip_filler\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_bytep sp=row;
+ png_bytep dp=row;
+ png_uint_32 row_width=row_info->width;
+ png_uint_32 i;
+
+ if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ (flags & PNG_FLAG_STRIP_ALPHA))) &&
+ row_info->channels == 4)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from RGBX or RGBA to RGB */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ dp+=3; sp+=4;
+ for (i = 1; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp++;
+ }
+ }
+ /* This converts from XRGB or ARGB to RGB */
+ else
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
+ sp += 8; dp += 6;
+ for (i = 1; i < row_width; i++)
+ {
+ /* This could be (although png_memcpy is probably slower):
+ png_memcpy(dp, sp, 6);
+ sp += 8;
+ dp += 6;
+ */
+
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp += 2;
+ }
+ }
+ else
+ {
+ /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
+ for (i = 0; i < row_width; i++)
+ {
+ /* This could be (although png_memcpy is probably slower):
+ png_memcpy(dp, sp, 6);
+ sp += 8;
+ dp += 6;
+ */
+
+ sp+=2;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 48;
+ row_info->rowbytes = row_width * 6;
+ }
+ row_info->channels = 3;
+ }
+ else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
+ (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ (flags & PNG_FLAG_STRIP_ALPHA))) &&
+ row_info->channels == 2)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from GX or GA to G */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ sp++;
+ }
+ }
+ /* This converts from XG or AG to G */
+ else
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This converts from GGXX or GGAA to GG */
+ sp += 4; dp += 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp += 2;
+ }
+ }
+ else
+ {
+ /* This converts from XXGG or AAGG to GG */
+ for (i = 0; i < row_width; i++)
+ {
+ sp += 2;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ row_info->channels = 1;
+ }
+ if (flags & PNG_FLAG_STRIP_ALPHA)
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ }
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_bgr\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 3)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 4)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 6)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 8)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ }
+ }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+ user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+ png_debug(1, "in png_set_user_transform_info\n");
+ if(png_ptr == NULL) return;
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ png_ptr->user_transform_ptr = user_transform_ptr;
+ png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+ png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+#else
+ if(user_transform_ptr || user_transform_depth || user_transform_channels)
+ png_warning(png_ptr,
+ "This version of libpng does not support user transform info");
+#endif
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions. The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if (png_ptr == NULL) return (NULL);
+ return ((png_voidp)png_ptr->user_transform_ptr);
+#else
+ return (NULL);
+#endif
+}
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngvcrd.c b/kernel/kls_png/ksquirrel-libs-png/pngvcrd.c
new file mode 100644
index 0000000..ce4233e
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngvcrd.c
@@ -0,0 +1 @@
+/* pnggvrd.c was removed from libpng-1.2.20. */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngwio.c b/kernel/kls_png/ksquirrel-libs-png/pngwio.c
new file mode 100644
index 0000000..371a4fa
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngwio.c
@@ -0,0 +1,234 @@
+
+/* pngwio.c - functions for data output
+ *
+ * Last changed in libpng 1.2.13 November 13, 2006
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2006 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all output. Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods. Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using. The default routine
+ writes to a file pointer. Note that this routine sometimes gets called
+ with very small lengths, so you should implement some kind of simple
+ buffering if you are using unbuffered writes. This should never be asked
+ to write more than 64K on a 16 bit machine. */
+
+void /* PRIVATE */
+png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ if (png_ptr->write_data_fn != NULL )
+ (*(png_ptr->write_data_fn))(png_ptr, data, length);
+ else
+ png_error(png_ptr, "Call to NULL write function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function that does the actual writing of data. If you are
+ not writing to a standard C stream, you should create a replacement
+ write_data function and use it at run time with png_set_write_fn(), rather
+ than changing the library. */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+
+ if(png_ptr == NULL) return;
+#if defined(_WIN32_WCE)
+ if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+#endif
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+ png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
+ png_FILE_p io_ptr;
+
+ if(png_ptr == NULL) return;
+ /* Check if data really is near. If so, use usual code. */
+ near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)near_data == data)
+ {
+#if defined(_WIN32_WCE)
+ if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fwrite(near_data, 1, length, io_ptr);
+#endif
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t written, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ written = MIN(NEAR_BUF_SIZE, remaining);
+ png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+#if defined(_WIN32_WCE)
+ if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
+ err = 0;
+#else
+ err = fwrite(buf, 1, written, io_ptr);
+#endif
+ if (err != written)
+ break;
+ else
+ check += err;
+ data += written;
+ remaining -= written;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+
+#endif
+#endif
+
+/* This function is called to output any data pending writing (normally
+ to disk). After png_flush is called, there should be no data pending
+ writing in any buffers. */
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+void /* PRIVATE */
+png_flush(png_structp png_ptr)
+{
+ if (png_ptr->output_flush_fn != NULL)
+ (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+void PNGAPI
+png_default_flush(png_structp png_ptr)
+{
+#if !defined(_WIN32_WCE)
+ png_FILE_p io_ptr;
+#endif
+ if(png_ptr == NULL) return;
+#if !defined(_WIN32_WCE)
+ io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+ if (io_ptr != NULL)
+ fflush(io_ptr);
+#endif
+}
+#endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ libpng if standard C streams aren't being used.
+
+ This function takes as its arguments:
+ png_ptr - pointer to a png output data structure
+ io_ptr - pointer to user supplied structure containing info about
+ the output functions. May be NULL.
+ write_data_fn - pointer to a new output function that takes as its
+ arguments a pointer to a png_struct, a pointer to
+ data to be written, and a 32-bit unsigned int that is
+ the number of bytes to be written. The new write
+ function should call png_error(png_ptr, "Error msg")
+ to exit and output any fatal error messages.
+ flush_data_fn - pointer to a new flush function that takes as its
+ arguments a pointer to a png_struct. After a call to
+ the flush function, there should be no data in any buffers
+ or pending transmission. If the output method doesn't do
+ any buffering of ouput, a function prototype must still be
+ supplied although it doesn't have to do anything. If
+ PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ time, output_flush_fn will be ignored, although it must be
+ supplied for compatibility. */
+void PNGAPI
+png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+ if(png_ptr == NULL) return;
+ png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+ if (write_data_fn != NULL)
+ png_ptr->write_data_fn = write_data_fn;
+ else
+ png_ptr->write_data_fn = png_default_write_data;
+#else
+ png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+ if (output_flush_fn != NULL)
+ png_ptr->output_flush_fn = output_flush_fn;
+ else
+ png_ptr->output_flush_fn = png_default_flush;
+#else
+ png_ptr->output_flush_fn = output_flush_fn;
+#endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+ /* It is an error to read while writing a png file */
+ if (png_ptr->read_data_fn != NULL)
+ {
+ png_ptr->read_data_fn = NULL;
+ png_warning(png_ptr,
+ "Attempted to set both read_data_fn and write_data_fn in");
+ png_warning(png_ptr,
+ "the same structure. Resetting read_data_fn to NULL.");
+ }
+}
+
+#if defined(USE_FAR_KEYWORD)
+#if defined(_MSC_VER)
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+ void *near_ptr;
+ void FAR *far_ptr;
+ FP_OFF(near_ptr) = FP_OFF(ptr);
+ far_ptr = (void FAR *)near_ptr;
+ if(check != 0)
+ if(FP_SEG(ptr) != FP_SEG(far_ptr))
+ png_error(png_ptr,"segment lost in conversion");
+ return(near_ptr);
+}
+# else
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+ void *near_ptr;
+ void FAR *far_ptr;
+ near_ptr = (void FAR *)ptr;
+ far_ptr = (void FAR *)near_ptr;
+ if(check != 0)
+ if(far_ptr != ptr)
+ png_error(png_ptr,"segment lost in conversion");
+ return(near_ptr);
+}
+# endif
+# endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngwrite.c b/kernel/kls_png/ksquirrel-libs-png/pngwrite.c
new file mode 100644
index 0000000..61ecb25
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngwrite.c
@@ -0,0 +1,1549 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * Last changed in libpng 1.2.15 January 5, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* get internal access to png.h */
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Writes all the PNG information. This is the suggested way to use the
+ * library. If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here. If you want the chunk written
+ * after the image data, put it in png_write_end(). I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file. If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_write_info_before_PLTE\n");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ {
+ png_write_sig(png_ptr); /* write PNG signature */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
+ {
+ png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
+ png_ptr->mng_features_permitted=0;
+ }
+#endif
+ /* write IHDR information. */
+ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+ info_ptr->filter_type,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ info_ptr->interlace_type);
+#else
+ 0);
+#endif
+ /* the rest of these check to see if the valid field has the appropriate
+ flag set, and if it does, writes the chunk. */
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_gAMA)
+ {
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_write_gAMA(png_ptr, info_ptr->gamma);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
+# endif
+#endif
+ }
+#endif
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
+#endif
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_iCCP)
+ png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
+ info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_cHRM)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_write_cHRM(png_ptr,
+ info_ptr->x_white, info_ptr->y_white,
+ info_ptr->x_red, info_ptr->y_red,
+ info_ptr->x_green, info_ptr->y_green,
+ info_ptr->x_blue, info_ptr->y_blue);
+#else
+# ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_cHRM_fixed(png_ptr,
+ info_ptr->int_x_white, info_ptr->int_y_white,
+ info_ptr->int_x_red, info_ptr->int_y_red,
+ info_ptr->int_x_green, info_ptr->int_y_green,
+ info_ptr->int_x_blue, info_ptr->int_y_blue);
+# endif
+#endif
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks\n");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep=png_handle_as_unknown(png_ptr, up->name);
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ up->location && !(up->location & PNG_HAVE_PLTE) &&
+ !(up->location & PNG_HAVE_IDAT) &&
+ ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+ png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+ }
+}
+
+void PNGAPI
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+ int i;
+#endif
+
+ png_debug(1, "in png_write_info\n");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+
+ if (info_ptr->valid & PNG_INFO_PLTE)
+ png_write_PLTE(png_ptr, info_ptr->palette,
+ (png_uint_32)info_ptr->num_palette);
+ else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Valid palette required for paletted images");
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_tRNS)
+ {
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ /* invert the alpha channel (in tRNS) */
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+ info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ int j;
+ for (j=0; j<(int)info_ptr->num_trans; j++)
+ info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
+ }
+#endif
+ png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
+ info_ptr->num_trans, info_ptr->color_type);
+ }
+#endif
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_bKGD)
+ png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_hIST)
+ png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+ info_ptr->offset_unit_type);
+#endif
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pCAL)
+ png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+ info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+ info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sCAL)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+ png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_s_width, info_ptr->scal_s_height);
+#else
+ png_warning(png_ptr,
+ "png_write_sCAL not supported; sCAL chunk not written.");
+#endif
+#endif
+#endif
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+ info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_tIME)
+ {
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+ png_ptr->mode |= PNG_WROTE_tIME;
+ }
+#endif
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sPLT)
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+ /* Check to see if we need to write text chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing header text chunk %d, type %d\n", i,
+ info_ptr->text[i].compression);
+ /* an internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+ /* write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ /* If we want a compressed text chunk */
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+ {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+ /* write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+ /* write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text,
+ 0);
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ }
+#endif
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_acTL)
+ png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks\n");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep=png_handle_as_unknown(png_ptr, up->name);
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ up->location && (up->location & PNG_HAVE_PLTE) &&
+ !(up->location & PNG_HAVE_IDAT) &&
+ ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+}
+
+/* Writes the end of the PNG file. If you don't want to write comments or
+ * time information, you can pass NULL for info. If you already wrote these
+ * in png_write_info(), do not write them again here. If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_write_end\n");
+ if (png_ptr == NULL)
+ return;
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "No IDATs written into file");
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
+ png_error(png_ptr, "Not enough frames written");
+#endif
+
+ /* see if user wants us to write information chunks */
+ if (info_ptr != NULL)
+ {
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+ int i; /* local index variable */
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+ /* check to see if user has supplied a time chunk */
+ if ((info_ptr->valid & PNG_INFO_tIME) &&
+ !(png_ptr->mode & PNG_WROTE_tIME))
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+ /* loop through comment chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
+ info_ptr->text[i].compression);
+ /* an internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+ /* write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+ {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+ /* write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+ /* write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0);
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks\n");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep=png_handle_as_unknown(png_ptr, up->name);
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ up->location && (up->location & PNG_AFTER_IDAT) &&
+ ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* write end of PNG file */
+ png_write_IEND(png_ptr);
+}
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
+{
+ png_debug(1, "in png_convert_from_struct_tm\n");
+ ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+ ptime->month = (png_byte)(ttime->tm_mon + 1);
+ ptime->day = (png_byte)ttime->tm_mday;
+ ptime->hour = (png_byte)ttime->tm_hour;
+ ptime->minute = (png_byte)ttime->tm_min;
+ ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+ struct tm *tbuf;
+
+ png_debug(1, "in png_convert_from_time_t\n");
+ tbuf = gmtime(&ttime);
+ png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_structp png_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+ int i;
+ png_debug(1, "in png_create_write_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+ (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (png_ptr == NULL)
+ return (NULL);
+
+ /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_ptr->jmpbuf))
+#endif
+ {
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf=NULL;
+ png_destroy_struct(png_ptr);
+ return (NULL);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+ i=0;
+ do
+ {
+ if(user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first digit.
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[80];
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "Incompatible libpng version in application and library");
+ }
+ }
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+
+ png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+ png_flush_ptr_NULL);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+ 1, png_doublep_NULL, png_doublep_NULL);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then encounter
+ a png_error() will longjmp here. Since the jmpbuf is then meaningless we
+ abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+ PNG_ABORT();
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#else
+ if (setjmp(png_ptr->jmpbuf))
+ PNG_ABORT();
+#endif
+#endif
+ return (png_ptr);
+}
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+
+void PNGAPI
+png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size, png_size_t png_info_size)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+ if(png_ptr == NULL) return;
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ if(png_sizeof(png_struct) > png_struct_size ||
+ png_sizeof(png_info) > png_info_size)
+ {
+ char msg[80];
+ png_ptr->warning_fn=NULL;
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+ }
+#endif
+ if(png_sizeof(png_struct) > png_struct_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The png struct allocated by the application for writing is too small.");
+ }
+ if(png_sizeof(png_info) > png_info_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The info struct allocated by the application for writing is too small.");
+ }
+ png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+#endif /* PNG_1_0_X || PNG_1_2_X */
+
+
+void PNGAPI
+png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size)
+{
+ png_structp png_ptr=*ptr_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+
+ int i = 0;
+
+ if (png_ptr == NULL)
+ return;
+
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ {
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+ png_ptr->warning_fn=NULL;
+ png_warning(png_ptr,
+ "Application uses deprecated png_write_init() and should be recompiled.");
+ break;
+#endif
+ }
+ } while (png_libpng_ver[i++]);
+
+ png_debug(1, "in png_write_init_3\n");
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* save jump buffer and error functions */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+ if (png_sizeof(png_struct) > png_struct_size)
+ {
+ png_destroy_struct(png_ptr);
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+ *ptr_ptr = png_ptr;
+ }
+
+ /* reset all variables to 0 */
+ png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+ /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* restore jump buffer */
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+ png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+ png_flush_ptr_NULL);
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+ 1, png_doublep_NULL, png_doublep_NULL);
+#endif
+}
+
+/* Write a few rows of image data. If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structp png_ptr, png_bytepp row,
+ png_uint_32 num_rows)
+{
+ png_uint_32 i; /* row counter */
+ png_bytepp rp; /* row pointer */
+
+ png_debug(1, "in png_write_rows\n");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* loop through the rows */
+ for (i = 0, rp = row; i < num_rows; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+}
+
+/* Write the image. You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structp png_ptr, png_bytepp image)
+{
+ png_uint_32 i; /* row index */
+ int pass, num_pass; /* pass variables */
+ png_bytepp rp; /* points to current row */
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug(1, "in png_write_image\n");
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* intialize interlace handling. If image is not interlaced,
+ this will set pass to 1 */
+ num_pass = png_set_interlace_handling(png_ptr);
+#else
+ num_pass = 1;
+#endif
+ /* loop through passes */
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ /* loop through image */
+ for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+ }
+}
+
+/* called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structp png_ptr, png_bytep row)
+{
+ if (png_ptr == NULL)
+ return;
+ png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
+ png_ptr->row_number, png_ptr->pass);
+
+ /* initialize transformations and other stuff if first time */
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* make sure we wrote the header info */
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ png_error(png_ptr,
+ "png_write_info was never called before png_write_row.");
+
+ /* check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
+#endif
+
+ png_write_start_row(png_ptr);
+ }
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* if interlaced and not interested in row, return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 3:
+ if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 4:
+ if ((png_ptr->row_number & 0x03) != 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 5:
+ if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 6:
+ if (!(png_ptr->row_number & 0x01))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ /* set up row info for transformations */
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->usr_width;
+ png_ptr->row_info.channels = png_ptr->usr_channels;
+ png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
+ png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+ png_ptr->row_info.channels);
+
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+
+ png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
+ png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
+ png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
+ png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
+ png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
+ png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
+
+ /* Copy user's row into buffer, leaving room for filter byte. */
+ png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
+ png_ptr->row_info.rowbytes);
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* handle interlacing */
+ if (png_ptr->interlaced && png_ptr->pass < 6 &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_do_write_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass);
+ /* this should always get caught above, but still ... */
+ if (!(png_ptr->row_info.width))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ }
+#endif
+
+ /* handle other transformations */
+ if (png_ptr->transformations)
+ png_do_write_transformations(png_ptr);
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+ }
+#endif
+
+ /* Find a filter if necessary, filter the row and write it out. */
+ png_write_find_filter(png_ptr, &(png_ptr->row_info));
+
+ if (png_ptr->write_row_fn != NULL)
+ (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structp png_ptr, int nrows)
+{
+ png_debug(1, "in png_set_flush\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structp png_ptr)
+{
+ int wrote_IDAT;
+
+ png_debug(1, "in png_write_flush\n");
+ if (png_ptr == NULL)
+ return;
+ /* We have already written out all of the data */
+ if (png_ptr->row_number >= png_ptr->num_rows)
+ return;
+
+ do
+ {
+ int ret;
+
+ /* compress the data */
+ ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+ wrote_IDAT = 0;
+
+ /* check for compression errors */
+ if (ret != Z_OK)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ wrote_IDAT = 1;
+ }
+ } while(wrote_IDAT == 1);
+
+ /* If there is any data left to be output, write it into a new IDAT */
+ if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
+ {
+ /* write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ png_ptr->flush_rows = 0;
+ png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* free all memory used by the write */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn = NULL;
+ png_voidp mem_ptr = NULL;
+#endif
+
+ png_debug(1, "in png_destroy_write_struct\n");
+ if (png_ptr_ptr != NULL)
+ {
+ png_ptr = *png_ptr_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+#endif
+ }
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->num_chunk_list)
+ {
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ png_ptr->num_chunk_list=0;
+ }
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+
+ if (png_ptr != NULL)
+ {
+ png_write_destroy(png_ptr);
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ *png_ptr_ptr = NULL;
+ }
+}
+
+
+/* Free any memory used in png_ptr struct (old method) */
+void /* PRIVATE */
+png_write_destroy(png_structp png_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* save jump buffer */
+#endif
+ png_error_ptr error_fn;
+ png_error_ptr warning_fn;
+ png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+#endif
+
+ png_debug(1, "in png_write_destroy\n");
+ /* free any memory zlib uses */
+ deflateEnd(&png_ptr->zstream);
+
+ /* free our memory. png_free checks NULL for us. */
+ png_free(png_ptr, png_ptr->zbuf);
+ png_free(png_ptr, png_ptr->row_buf);
+ png_free(png_ptr, png_ptr->prev_row);
+ png_free(png_ptr, png_ptr->sub_row);
+ png_free(png_ptr, png_ptr->up_row);
+ png_free(png_ptr, png_ptr->avg_row);
+ png_free(png_ptr, png_ptr->paeth_row);
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_free(png_ptr, png_ptr->prev_filters);
+ png_free(png_ptr, png_ptr->filter_weights);
+ png_free(png_ptr, png_ptr->inv_filter_weights);
+ png_free(png_ptr, png_ptr->filter_costs);
+ png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* reset structure */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+ error_fn = png_ptr->error_fn;
+ warning_fn = png_ptr->warning_fn;
+ error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+#endif
+
+ png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+ png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structp png_ptr, int method, int filters)
+{
+ png_debug(1, "in png_set_filter\n");
+ if (png_ptr == NULL)
+ return;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (method == PNG_INTRAPIXEL_DIFFERENCING))
+ method = PNG_FILTER_TYPE_BASE;
+#endif
+ if (method == PNG_FILTER_TYPE_BASE)
+ {
+ switch (filters & (PNG_ALL_FILTERS | 0x07))
+ {
+#ifndef PNG_NO_WRITE_FILTER
+ case 5:
+ case 6:
+ case 7: png_warning(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_NO_WRITE_FILTER */
+ case PNG_FILTER_VALUE_NONE:
+ png_ptr->do_filter=PNG_FILTER_NONE; break;
+#ifndef PNG_NO_WRITE_FILTER
+ case PNG_FILTER_VALUE_SUB:
+ png_ptr->do_filter=PNG_FILTER_SUB; break;
+ case PNG_FILTER_VALUE_UP:
+ png_ptr->do_filter=PNG_FILTER_UP; break;
+ case PNG_FILTER_VALUE_AVG:
+ png_ptr->do_filter=PNG_FILTER_AVG; break;
+ case PNG_FILTER_VALUE_PAETH:
+ png_ptr->do_filter=PNG_FILTER_PAETH; break;
+ default: png_ptr->do_filter = (png_byte)filters; break;
+#else
+ default: png_warning(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_NO_WRITE_FILTER */
+ }
+
+ /* If we have allocated the row_buf, this means we have already started
+ * with the image and we should have allocated all of the filter buffers
+ * that have been selected. If prev_row isn't already allocated, then
+ * it is too late to start using the filters that need it, since we
+ * will be missing the data in the previous row. If an application
+ * wants to start and stop using particular filters during compression,
+ * it should start out with all of the filters, and then add and
+ * remove them after the start of compression.
+ */
+ if (png_ptr->row_buf != NULL)
+ {
+#ifndef PNG_NO_WRITE_FILTER
+ if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Up filter after starting");
+ png_ptr->do_filter &= ~PNG_FILTER_UP;
+ }
+ else
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Average filter after starting");
+ png_ptr->do_filter &= ~PNG_FILTER_AVG;
+ }
+ else
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+ png_ptr->paeth_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Paeth filter after starting");
+ png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+ }
+ else
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+
+ if (png_ptr->do_filter == PNG_NO_FILTERS)
+#endif /* PNG_NO_WRITE_FILTER */
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ }
+ }
+ else
+ png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline. While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
+void PNGAPI
+png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
+ int num_weights, png_doublep filter_weights,
+ png_doublep filter_costs)
+{
+ int i;
+
+ png_debug(1, "in png_set_filter_heuristics\n");
+ if (png_ptr == NULL)
+ return;
+ if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
+ {
+ png_warning(png_ptr, "Unknown filter heuristic method");
+ return;
+ }
+
+ if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
+ {
+ heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+ }
+
+ if (num_weights < 0 || filter_weights == NULL ||
+ heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+ {
+ num_weights = 0;
+ }
+
+ png_ptr->num_prev_filters = (png_byte)num_weights;
+ png_ptr->heuristic_method = (png_byte)heuristic_method;
+
+ if (num_weights > 0)
+ {
+ if (png_ptr->prev_filters == NULL)
+ {
+ png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_byte) * num_weights));
+
+ /* To make sure that the weighting starts out fairly */
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->prev_filters[i] = 255;
+ }
+ }
+
+ if (png_ptr->filter_weights == NULL)
+ {
+ png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+
+ png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+ }
+
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] < 0.0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+ else
+ {
+ png_ptr->inv_filter_weights[i] =
+ (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
+ png_ptr->filter_weights[i] =
+ (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
+ }
+ }
+ }
+
+ /* If, in the future, there are other filter methods, this would
+ * need to be based on png_ptr->filter.
+ */
+ if (png_ptr->filter_costs == NULL)
+ {
+ png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+ png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ if (filter_costs == NULL || filter_costs[i] < 0.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+ else if (filter_costs[i] >= 1.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
+ png_ptr->filter_costs[i] =
+ (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
+ }
+ }
+}
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void PNGAPI
+png_set_compression_level(png_structp png_ptr, int level)
+{
+ png_debug(1, "in png_set_compression_level\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
+ png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_compression_mem_level\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
+ png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_compression_strategy\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+ png_ptr->zlib_strategy = strategy;
+}
+
+void PNGAPI
+png_set_compression_window_bits(png_structp png_ptr, int window_bits)
+{
+ if (png_ptr == NULL)
+ return;
+ if (window_bits > 15)
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ else if (window_bits < 8)
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+#ifndef WBITS_8_OK
+ /* avoid libpng bug with 256-byte windows */
+ if (window_bits == 8)
+ {
+ png_warning(png_ptr, "Compression window is being reset to 512");
+ window_bits=9;
+ }
+#endif
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
+ png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structp png_ptr, int method)
+{
+ png_debug(1, "in png_set_compression_method\n");
+ if (png_ptr == NULL)
+ return;
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
+ png_ptr->zlib_method = method;
+}
+
+void PNGAPI
+png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->write_row_fn = write_row_fn;
+}
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+ write_user_transform_fn)
+{
+ png_debug(1, "in png_set_write_user_transform_fn\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_write_png(png_structp png_ptr, png_infop info_ptr,
+ int transforms, voidp params)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ /* invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* Write the file header information. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* ------ these transformations don't touch the info structure ------- */
+
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+ /* invert monochrome pixels */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+ /* Shift the pixels up to a legal bit depth and fill in
+ * as appropriate to correctly scale the image.
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && (info_ptr->valid & PNG_INFO_sBIT))
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+ /* pack pixels into bytes */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+ /* swap location of alpha bytes from ARGB to RGBA */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+ /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+ * RGB (4 channels -> 3 channels). The second parameter is not used.
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+ /* flip BGR pixels to RGB */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+ /* swap bytes of 16-bit files to most significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+ /* swap bits of 1, 2, 4 bit packed pixel formats */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+ /* ----------------------- end of transformations ------------------- */
+
+ /* write the bits */
+ if (info_ptr->valid & PNG_INFO_IDAT)
+ png_write_image(png_ptr, info_ptr->row_pointers);
+
+ /* It is REQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ transforms = transforms; /* quiet compiler warnings */
+ params = params;
+}
+#endif
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+void PNGAPI
+png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
+ png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
+ png_byte blend_op)
+{
+ png_debug(1, "in png_write_frame_head\n");
+
+ /* there is a chance this has been set after png_write_info was called,
+ * so it would be set but not written. is there a way to be sure? */
+ if (!(info_ptr->valid & PNG_INFO_acTL))
+ png_error(png_ptr, "png_write_frame_head(): acTL not set");
+
+ png_write_reset(png_ptr);
+
+ png_write_reinit(png_ptr, info_ptr, width, height);
+
+ if ( !(png_ptr->num_frames_written == 0 &&
+ (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
+ png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
+ delay_num, delay_den, dispose_op, blend_op);
+}
+
+void PNGAPI
+png_write_frame_tail(png_structp png_ptr, png_infop zpng_info)
+{
+ png_debug(1, "in png_write_frame_tail\n");
+
+ png_ptr->num_frames_written++;
+}
+#endif /* PNG_WRITE_APNG_SUPPORTED */
+
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngwtran.c b/kernel/kls_png/ksquirrel-libs-png/pngwtran.c
new file mode 100644
index 0000000..0372fe6
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngwtran.c
@@ -0,0 +1,572 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * Last changed in libpng 1.2.9 April 14, 2006
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2006 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Transform the data according to the user's wishes. The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_do_write_transformations\n");
+
+ if (png_ptr == NULL)
+ return;
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ if(png_ptr->write_user_transform_fn != NULL)
+ (*(png_ptr->write_user_transform_fn)) /* user write transform function */
+ (png_ptr, /* png_ptr */
+ &(png_ptr->row_info), /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_uint_32 rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->flags);
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->bit_depth);
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+}
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
+ * row_info bit depth should be 8 (one pixel per byte). The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void /* PRIVATE */
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+ png_debug(1, "in png_do_pack\n");
+ if (row_info->bit_depth == 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->channels == 1)
+ {
+ switch ((int)bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int mask, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ mask = 0x80;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp != 0)
+ v |= mask;
+ sp++;
+ if (mask > 1)
+ mask >>= 1;
+ else
+ {
+ mask = 0x80;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ }
+ if (mask != 0x80)
+ *dp = (png_byte)v;
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 6;
+ v = 0;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x03);
+ v |= (value << shift);
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ else
+ shift -= 2;
+ sp++;
+ }
+ if (shift != 6)
+ *dp = (png_byte)v;
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 4;
+ v = 0;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x0f);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ else
+ shift -= 4;
+
+ sp++;
+ }
+ if (shift != 4)
+ *dp = (png_byte)v;
+ break;
+ }
+ }
+ row_info->bit_depth = (png_byte)bit_depth;
+ row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Shift pixel values to take advantage of whole range. Pass the
+ * true number of bits in bit_depth. The row should be packed
+ * according to row_info->bit_depth. Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void /* PRIVATE */
+png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
+{
+ png_debug(1, "in png_do_shift\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL &&
+#else
+ if (
+#endif
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift_start[4], shift_dec[4];
+ int channels = 0;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->red;
+ shift_dec[channels] = bit_depth->red;
+ channels++;
+ shift_start[channels] = row_info->bit_depth - bit_depth->green;
+ shift_dec[channels] = bit_depth->green;
+ channels++;
+ shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+ shift_dec[channels] = bit_depth->blue;
+ channels++;
+ }
+ else
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+ shift_dec[channels] = bit_depth->gray;
+ channels++;
+ }
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+ shift_dec[channels] = bit_depth->alpha;
+ channels++;
+ }
+
+ /* with low row depths, could only be grayscale, so one channel */
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_byte mask;
+ png_uint_32 row_bytes = row_info->rowbytes;
+
+ if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+ mask = 0x55;
+ else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+ mask = 0x11;
+ else
+ mask = 0xff;
+
+ for (i = 0; i < row_bytes; i++, bp++)
+ {
+ png_uint_16 v;
+ int j;
+
+ v = *bp;
+ *bp = 0;
+ for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+ {
+ if (j > 0)
+ *bp |= (png_byte)((v << j) & 0xff);
+ else
+ *bp |= (png_byte)((v >> (-j)) & mask);
+ }
+ }
+ }
+ else if (row_info->bit_depth == 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (i = 0; i < istop; i++, bp++)
+ {
+
+ png_uint_16 v;
+ int j;
+ int c = (int)(i%channels);
+
+ v = *bp;
+ *bp = 0;
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ *bp |= (png_byte)((v << j) & 0xff);
+ else
+ *bp |= (png_byte)((v >> (-j)) & 0xff);
+ }
+ }
+ }
+ else
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ int c = (int)(i%channels);
+ png_uint_16 value, v;
+ int j;
+
+ v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
+ value = 0;
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+ else
+ value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+ }
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from ARGB to RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+ /* This converts from AARRGGBB to RRGGBBAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from AG to GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+ /* This converts from AAGG to GGAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This inverts the alpha channel in RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=3; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=6; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This inverts the alpha channel in GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ /* This inverts the alpha channel in GGAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=2; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_intrapixel\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
+ *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
+ png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
+ png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
+ png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp+1) = (png_byte)(red & 0xff);
+ *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp+5) = (png_byte)(blue & 0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_png/ksquirrel-libs-png/pngwutil.c b/kernel/kls_png/ksquirrel-libs-png/pngwutil.c
new file mode 100644
index 0000000..a526c66
--- /dev/null
+++ b/kernel/kls_png/ksquirrel-libs-png/pngwutil.c
@@ -0,0 +1,2920 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * Last changed in libpng 1.2.19 August 19, 2007
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2007 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Place a 32-bit number into a buffer in PNG byte order. We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void PNGAPI
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format. If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.
+ */
+void PNGAPI
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void PNGAPI
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+ buf[0] = (png_byte)((i >> 8) & 0xff);
+ buf[1] = (png_byte)(i & 0xff);
+}
+
+/* Write a PNG chunk all at once. The type is an array of ASCII characters
+ * representing the chunk name. The array must be at least 4 bytes in
+ * length, and does not need to be null terminated. To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined. The length is the length of the data.
+ * All the data must be present. If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+void PNGAPI
+png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
+ png_bytep data, png_size_t length)
+{
+ if(png_ptr == NULL) return;
+ png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
+ png_write_chunk_data(png_ptr, data, length);
+ png_write_chunk_end(png_ptr);
+}
+
+/* Write the start of a PNG chunk. The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+void PNGAPI
+png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
+ png_uint_32 length)
+{
+ png_byte buf[4];
+ png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
+ if(png_ptr == NULL) return;
+
+ /* write the length */
+ png_save_uint_32(buf, length);
+ png_write_data(png_ptr, buf, (png_size_t)4);
+
+ /* write the chunk name */
+ png_write_data(png_ptr, chunk_name, (png_size_t)4);
+ /* reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_start().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_start().
+ */
+void PNGAPI
+png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ /* write the data, and run the CRC over it */
+ if(png_ptr == NULL) return;
+ if (data != NULL && length > 0)
+ {
+ png_calculate_crc(png_ptr, data, length);
+ png_write_data(png_ptr, data, length);
+ }
+}
+
+/* Finish a chunk started with png_write_chunk_start(). */
+void PNGAPI
+png_write_chunk_end(png_structp png_ptr)
+{
+ png_byte buf[4];
+
+ if(png_ptr == NULL) return;
+
+ /* write the crc */
+ png_save_uint_32(buf, png_ptr->crc);
+
+ png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Simple function to write the signature. If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void /* PRIVATE */
+png_write_sig(png_structp png_ptr)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ /* write the rest of the 8 byte signature */
+ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+ (png_size_t)8 - png_ptr->sig_bytes);
+ if(png_ptr->sig_bytes < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
+/*
+ * This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+ char *input; /* the uncompressed input data */
+ int input_len; /* its length */
+ int num_output_ptr; /* number of output pointers used */
+ int max_output_ptr; /* size of output_ptr */
+ png_charpp output_ptr; /* array of pointers to output */
+} compression_state;
+
+/* compress given text into storage in the png_ptr structure */
+static int /* PRIVATE */
+png_text_compress(png_structp png_ptr,
+ png_charp text, png_size_t text_len, int compression,
+ compression_state *comp)
+{
+ int ret;
+
+ comp->num_output_ptr = 0;
+ comp->max_output_ptr = 0;
+ comp->output_ptr = NULL;
+ comp->input = NULL;
+ comp->input_len = 0;
+
+ /* we may just want to pass the text right through */
+ if (compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+ comp->input = text;
+ comp->input_len = text_len;
+ return((int)text_len);
+ }
+
+ if (compression >= PNG_TEXT_COMPRESSION_LAST)
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[50];
+ png_snprintf(msg, 50, "Unknown compression type %d", compression);
+ png_warning(png_ptr, msg);
+#else
+ png_warning(png_ptr, "Unknown compression type");
+#endif
+ }
+
+ /* We can't write the chunk until we find out how much data we have,
+ * which means we need to run the compressor first and save the
+ * output. This shouldn't be a problem, as the vast majority of
+ * comments should be reasonable, but we will set up an array of
+ * malloc'd pointers to be sure.
+ *
+ * If we knew the application was well behaved, we could simplify this
+ * greatly by assuming we can always malloc an output buffer large
+ * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+ * and malloc this directly. The only time this would be a bad idea is
+ * if we can't malloc more than 64K and we have 64K of random input
+ * data, or if the input string is incredibly large (although this
+ * wouldn't cause a failure, just a slowdown due to swapping).
+ */
+
+ /* set up the compression buffers */
+ png_ptr->zstream.avail_in = (uInt)text_len;
+ png_ptr->zstream.next_in = (Bytef *)text;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+ /* this is the same compression loop as in png_write_row() */
+ do
+ {
+ /* compress the data */
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+ if (ret != Z_OK)
+ {
+ /* error */
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ /* check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* make sure the output array has room */
+ if (comp->num_output_ptr >= comp->max_output_ptr)
+ {
+ int old_max;
+
+ old_max = comp->max_output_ptr;
+ comp->max_output_ptr = comp->num_output_ptr + 4;
+ if (comp->output_ptr != NULL)
+ {
+ png_charpp old_ptr;
+
+ old_ptr = comp->output_ptr;
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr *
+ png_sizeof (png_charpp)));
+ png_memcpy(comp->output_ptr, old_ptr, old_max
+ * png_sizeof (png_charp));
+ png_free(png_ptr, old_ptr);
+ }
+ else
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr *
+ png_sizeof (png_charp)));
+ }
+
+ /* save the data */
+ comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ comp->num_output_ptr++;
+
+ /* and reset the buffer */
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ }
+ /* continue until we don't have any more to compress */
+ } while (png_ptr->zstream.avail_in);
+
+ /* finish the compression */
+ do
+ {
+ /* tell zlib we are finished */
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
+
+ if (ret == Z_OK)
+ {
+ /* check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* check to make sure our output array has room */
+ if (comp->num_output_ptr >= comp->max_output_ptr)
+ {
+ int old_max;
+
+ old_max = comp->max_output_ptr;
+ comp->max_output_ptr = comp->num_output_ptr + 4;
+ if (comp->output_ptr != NULL)
+ {
+ png_charpp old_ptr;
+
+ old_ptr = comp->output_ptr;
+ /* This could be optimized to realloc() */
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr *
+ png_sizeof (png_charpp)));
+ png_memcpy(comp->output_ptr, old_ptr,
+ old_max * png_sizeof (png_charp));
+ png_free(png_ptr, old_ptr);
+ }
+ else
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr *
+ png_sizeof (png_charp)));
+ }
+
+ /* save off the data */
+ comp->output_ptr[comp->num_output_ptr] =
+ (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ comp->num_output_ptr++;
+
+ /* and reset the buffer pointers */
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ }
+ }
+ else if (ret != Z_STREAM_END)
+ {
+ /* we got an error */
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ } while (ret != Z_STREAM_END);
+
+ /* text length is number of buffers plus last buffer */
+ text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+ text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+ return((int)text_len);
+}
+
+/* ship the compressed text out via chunk writes */
+static void /* PRIVATE */
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+ int i;
+
+ /* handle the no-compression case */
+ if (comp->input)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)comp->input,
+ (png_size_t)comp->input_len);
+ return;
+ }
+
+ /* write saved output buffers, if any */
+ for (i = 0; i < comp->num_output_ptr; i++)
+ {
+ png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
+ png_ptr->zbuf_size);
+ png_free(png_ptr, comp->output_ptr[i]);
+ comp->output_ptr[i]=NULL;
+ }
+ if (comp->max_output_ptr != 0)
+ png_free(png_ptr, comp->output_ptr);
+ comp->output_ptr=NULL;
+ /* write anything left in zbuf */
+ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+ png_write_chunk_data(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+ /* reset zlib for another zTXt/iTXt or image data */
+ deflateReset(&png_ptr->zstream);
+ png_ptr->zstream.data_type = Z_BINARY;
+}
+#endif
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information. Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+ int bit_depth, int color_type, int compression_type, int filter_type,
+ int interlace_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IHDR;
+#endif
+ png_byte buf[13]; /* buffer to store the IHDR info */
+
+ png_debug(1, "in png_write_IHDR\n");
+ /* Check that we have valid input data from the application info */
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16: png_ptr->channels = 1; break;
+ default: png_error(png_ptr,"Invalid bit depth for grayscale image");
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for RGB image");
+ png_ptr->channels = 3;
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8: png_ptr->channels = 1; break;
+ default: png_error(png_ptr, "Invalid bit depth for paletted image");
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+ png_ptr->channels = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for RGBA image");
+ png_ptr->channels = 4;
+ break;
+ default:
+ png_error(png_ptr, "Invalid image color type specified");
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid compression type specified");
+ compression_type = PNG_COMPRESSION_TYPE_BASE;
+ }
+
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+ filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid filter type specified");
+ filter_type = PNG_FILTER_TYPE_BASE;
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ if (interlace_type != PNG_INTERLACE_NONE &&
+ interlace_type != PNG_INTERLACE_ADAM7)
+ {
+ png_warning(png_ptr, "Invalid interlace type specified");
+ interlace_type = PNG_INTERLACE_ADAM7;
+ }
+#else
+ interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+ /* save off the relevent information */
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->color_type = (png_byte)color_type;
+ png_ptr->interlaced = (png_byte)interlace_type;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+ png_ptr->width = width;
+ png_ptr->height = height;
+
+ png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+ /* set the usr info, so any transformations can modify it */
+ png_ptr->usr_width = png_ptr->width;
+ png_ptr->usr_bit_depth = png_ptr->bit_depth;
+ png_ptr->usr_channels = png_ptr->channels;
+
+ /* pack the header information into the buffer */
+ png_save_uint_32(buf, width);
+ png_save_uint_32(buf + 4, height);
+ buf[8] = (png_byte)bit_depth;
+ buf[9] = (png_byte)color_type;
+ buf[10] = (png_byte)compression_type;
+ buf[11] = (png_byte)filter_type;
+ buf[12] = (png_byte)interlace_type;
+
+ /* write the chunk */
+ png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ png_ptr->first_frame_width = width;
+ png_ptr->first_frame_height = height;
+#endif
+
+ /* initialize zlib with PNG info */
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+ if (!(png_ptr->do_filter))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ png_ptr->bit_depth < 8)
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ else
+ png_ptr->do_filter = PNG_ALL_FILTERS;
+ }
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
+ {
+ if (png_ptr->do_filter != PNG_FILTER_NONE)
+ png_ptr->zlib_strategy = Z_FILTERED;
+ else
+ png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
+ }
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
+ png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
+ png_ptr->zlib_mem_level = 8;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
+ png_ptr->zlib_window_bits = 15;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
+ png_ptr->zlib_method = 8;
+ if (deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+ png_ptr->zlib_method, png_ptr->zlib_window_bits,
+ png_ptr->zlib_mem_level, png_ptr->zlib_strategy) != Z_OK)
+ png_error(png_ptr, "zlib failed to initialize compressor");
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ /* libpng is not interested in zstream.data_type */
+ /* set it to a predefined value, to avoid its evaluation inside zlib */
+ png_ptr->zstream.data_type = Z_BINARY;
+
+ png_ptr->mode = PNG_HAVE_IHDR;
+}
+
+/* write the palette. We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_PLTE;
+#endif
+ png_uint_32 i;
+ png_colorp pal_ptr;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_PLTE\n");
+ if ((
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+ num_pal == 0) || num_pal > 256)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_error(png_ptr, "Invalid number of colors in palette");
+ }
+ else
+ {
+ png_warning(png_ptr, "Invalid number of colors in palette");
+ return;
+ }
+ }
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring request to write a PLTE chunk in grayscale PNG");
+ return;
+ }
+
+ png_ptr->num_palette = (png_uint_16)num_pal;
+ png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
+
+ png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
+#ifndef PNG_NO_POINTER_INDEXING
+ for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+ {
+ buf[0] = pal_ptr->red;
+ buf[1] = pal_ptr->green;
+ buf[2] = pal_ptr->blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+#else
+ /* This is a little slower but some buggy compilers need to do this instead */
+ pal_ptr=palette;
+ for (i = 0; i < num_pal; i++)
+ {
+ buf[0] = pal_ptr[i].red;
+ buf[1] = pal_ptr[i].green;
+ buf[2] = pal_ptr[i].blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+#endif
+ png_write_chunk_end(png_ptr);
+ png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* write an IDAT chunk */
+void /* PRIVATE */
+png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ PNG_fdAT;
+#endif
+#endif
+ png_debug(1, "in png_write_IDAT\n");
+
+ /* Optimize the CMF field in the zlib stream. */
+ /* This hack of the zlib stream is compliant to the stream specification. */
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ {
+ unsigned int z_cmf = data[0]; /* zlib compression method and flags */
+ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+ {
+ /* Avoid memory underflows and multiplication overflows. */
+ /* The conditions below are practically always satisfied;
+ however, they still must be checked. */
+ if (length >= 2 &&
+ png_ptr->height < 16384 && png_ptr->width < 16384)
+ {
+ png_uint_32 uncompressed_idat_size = png_ptr->height *
+ ((png_ptr->width *
+ png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
+ unsigned int z_cinfo = z_cmf >> 4;
+ unsigned int half_z_window_size = 1 << (z_cinfo + 7);
+ while (uncompressed_idat_size <= half_z_window_size &&
+ half_z_window_size >= 256)
+ {
+ z_cinfo--;
+ half_z_window_size >>= 1;
+ }
+ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+ if (data[0] != (png_byte)z_cmf)
+ {
+ data[0] = (png_byte)z_cmf;
+ data[1] &= 0xe0;
+ data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
+ }
+ }
+ }
+ else
+ png_error(png_ptr,
+ "Invalid zlib compression method or flags in IDAT");
+ }
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ if(png_ptr->num_frames_written == 0)
+#endif
+ png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+ else
+ {
+ png_byte buf[4];
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_fdAT, 4 + length);
+
+ png_save_uint_32(buf, png_ptr->next_seq_num);
+ png_write_chunk_data(png_ptr, buf, 4);
+
+ png_write_chunk_data(png_ptr, data, length);
+
+ png_write_chunk_end(png_ptr);
+
+ png_ptr->next_seq_num++;
+ }
+#endif
+
+ png_ptr->mode |= PNG_HAVE_IDAT;
+}
+
+/* write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IEND;
+#endif
+ png_debug(1, "in png_write_IEND\n");
+ png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
+ (png_size_t)0);
+ png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+/* write a gAMA chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA(png_structp png_ptr, double file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_gAMA;
+#endif
+ png_uint_32 igamma;
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA\n");
+ /* file_gamma is saved in 1/100,000ths */
+ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
+ png_save_uint_32(buf, igamma);
+ png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_gAMA;
+#endif
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA\n");
+ /* file_gamma is saved in 1/100,000ths */
+ png_save_uint_32(buf, (png_uint_32)file_gamma);
+ png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+/* write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structp png_ptr, int srgb_intent)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sRGB;
+#endif
+ png_byte buf[1];
+
+ png_debug(1, "in png_write_sRGB\n");
+ if(srgb_intent >= PNG_sRGB_INTENT_LAST)
+ png_warning(png_ptr,
+ "Invalid sRGB rendering intent specified");
+ buf[0]=(png_byte)srgb_intent;
+ png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+/* write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+ png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_iCCP;
+#endif
+ png_size_t name_len;
+ png_charp new_name;
+ compression_state comp;
+ int embedded_profile_len = 0;
+
+ png_debug(1, "in png_write_iCCP\n");
+
+ comp.num_output_ptr = 0;
+ comp.max_output_ptr = 0;
+ comp.output_ptr = NULL;
+ comp.input = NULL;
+ comp.input_len = 0;
+
+ if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
+ &new_name)) == 0)
+ {
+ png_warning(png_ptr, "Empty keyword in iCCP chunk");
+ return;
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_warning(png_ptr, "Unknown compression type in iCCP chunk");
+
+ if (profile == NULL)
+ profile_len = 0;
+
+ if (profile_len > 3)
+ embedded_profile_len =
+ ((*( (png_bytep)profile ))<<24) |
+ ((*( (png_bytep)profile+1))<<16) |
+ ((*( (png_bytep)profile+2))<< 8) |
+ ((*( (png_bytep)profile+3)) );
+
+ if (profile_len < embedded_profile_len)
+ {
+ png_warning(png_ptr,
+ "Embedded profile length too large in iCCP chunk");
+ return;
+ }
+
+ if (profile_len > embedded_profile_len)
+ {
+ png_warning(png_ptr,
+ "Truncating profile to actual length in iCCP chunk");
+ profile_len = embedded_profile_len;
+ }
+
+ if (profile_len)
+ profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
+ PNG_COMPRESSION_TYPE_BASE, &comp);
+
+ /* make sure we include the NULL after the name and the compression type */
+ png_write_chunk_start(png_ptr, png_iCCP,
+ (png_uint_32)name_len+profile_len+2);
+ new_name[name_len+1]=0x00;
+ png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
+
+ if (profile_len)
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+/* write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sPLT;
+#endif
+ png_size_t name_len;
+ png_charp new_name;
+ png_byte entrybuf[10];
+ int entry_size = (spalette->depth == 8 ? 6 : 10);
+ int palette_size = entry_size * spalette->nentries;
+ png_sPLT_entryp ep;
+#ifdef PNG_NO_POINTER_INDEXING
+ int i;
+#endif
+
+ png_debug(1, "in png_write_sPLT\n");
+ if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
+ spalette->name, &new_name))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in sPLT chunk");
+ return;
+ }
+
+ /* make sure we include the NULL after the name */
+ png_write_chunk_start(png_ptr, png_sPLT,
+ (png_uint_32)(name_len + 2 + palette_size));
+ png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
+ png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
+
+ /* loop through each palette entry, writing appropriately */
+#ifndef PNG_NO_POINTER_INDEXING
+ for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep->red;
+ entrybuf[1] = (png_byte)ep->green;
+ entrybuf[2] = (png_byte)ep->blue;
+ entrybuf[3] = (png_byte)ep->alpha;
+ png_save_uint_16(entrybuf + 4, ep->frequency);
+ }
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep->red);
+ png_save_uint_16(entrybuf + 2, ep->green);
+ png_save_uint_16(entrybuf + 4, ep->blue);
+ png_save_uint_16(entrybuf + 6, ep->alpha);
+ png_save_uint_16(entrybuf + 8, ep->frequency);
+ }
+ png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+ }
+#else
+ ep=spalette->entries;
+ for (i=0; i>spalette->nentries; i++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep[i].red;
+ entrybuf[1] = (png_byte)ep[i].green;
+ entrybuf[2] = (png_byte)ep[i].blue;
+ entrybuf[3] = (png_byte)ep[i].alpha;
+ png_save_uint_16(entrybuf + 4, ep[i].frequency);
+ }
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep[i].red);
+ png_save_uint_16(entrybuf + 2, ep[i].green);
+ png_save_uint_16(entrybuf + 4, ep[i].blue);
+ png_save_uint_16(entrybuf + 6, ep[i].alpha);
+ png_save_uint_16(entrybuf + 8, ep[i].frequency);
+ }
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
+ }
+#endif
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+/* write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sBIT;
+#endif
+ png_byte buf[4];
+ png_size_t size;
+
+ png_debug(1, "in png_write_sBIT\n");
+ /* make sure we don't depend upon the order of PNG_COLOR_8 */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_byte maxbits;
+
+ maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+ png_ptr->usr_bit_depth);
+ if (sbit->red == 0 || sbit->red > maxbits ||
+ sbit->green == 0 || sbit->green > maxbits ||
+ sbit->blue == 0 || sbit->blue > maxbits)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[0] = sbit->red;
+ buf[1] = sbit->green;
+ buf[2] = sbit->blue;
+ size = 3;
+ }
+ else
+ {
+ if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[0] = sbit->gray;
+ size = 1;
+ }
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[size++] = sbit->alpha;
+ }
+
+ png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
+}
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+/* write the cHRM chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
+ double red_x, double red_y, double green_x, double green_y,
+ double blue_x, double blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_cHRM;
+#endif
+ png_byte buf[32];
+ png_uint_32 itemp;
+
+ png_debug(1, "in png_write_cHRM\n");
+ /* each value is saved in 1/100,000ths */
+ if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
+ white_x + white_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+ fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
+#endif
+ return;
+ }
+ itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
+ png_save_uint_32(buf, itemp);
+ itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 4, itemp);
+
+ if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM red point specified");
+ return;
+ }
+ itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
+ png_save_uint_32(buf + 8, itemp);
+ itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 12, itemp);
+
+ if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM green point specified");
+ return;
+ }
+ itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
+ png_save_uint_32(buf + 16, itemp);
+ itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 20, itemp);
+
+ if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM blue point specified");
+ return;
+ }
+ itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
+ png_save_uint_32(buf + 24, itemp);
+ itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 28, itemp);
+
+ png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
+ png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
+ png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
+ png_fixed_point blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_cHRM;
+#endif
+ png_byte buf[32];
+
+ png_debug(1, "in png_write_cHRM\n");
+ /* each value is saved in 1/100,000ths */
+ if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid fixed cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+ fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
+#endif
+ return;
+ }
+ png_save_uint_32(buf, (png_uint_32)white_x);
+ png_save_uint_32(buf + 4, (png_uint_32)white_y);
+
+ if (red_x + red_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM fixed red point specified");
+ return;
+ }
+ png_save_uint_32(buf + 8, (png_uint_32)red_x);
+ png_save_uint_32(buf + 12, (png_uint_32)red_y);
+
+ if (green_x + green_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid fixed cHRM green point specified");
+ return;
+ }
+ png_save_uint_32(buf + 16, (png_uint_32)green_x);
+ png_save_uint_32(buf + 20, (png_uint_32)green_y);
+
+ if (blue_x + blue_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
+ return;
+ }
+ png_save_uint_32(buf + 24, (png_uint_32)blue_x);
+ png_save_uint_32(buf + 28, (png_uint_32)blue_y);
+
+ png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+/* write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
+ int num_trans, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tRNS;
+#endif
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_tRNS\n");
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+ {
+ png_warning(png_ptr,"Invalid number of transparent colors specified");
+ return;
+ }
+ /* write the chunk out as it is */
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans);
+ }
+ else if (color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ /* one 16 bit value */
+ if(tran->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+ return;
+ }
+ png_save_uint_16(buf, tran->gray);
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
+ }
+ else if (color_type == PNG_COLOR_TYPE_RGB)
+ {
+ /* three 16 bit values */
+ png_save_uint_16(buf, tran->red);
+ png_save_uint_16(buf + 2, tran->green);
+ png_save_uint_16(buf + 4, tran->blue);
+ if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ return;
+ }
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
+ }
+ else
+ {
+ png_warning(png_ptr, "Can't write tRNS with an alpha channel");
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+/* write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_bKGD;
+#endif
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_bKGD\n");
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ (png_ptr->num_palette ||
+ (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+ back->index > png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Invalid background palette index");
+ return;
+ }
+ buf[0] = back->index;
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
+ }
+ else if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_save_uint_16(buf, back->red);
+ png_save_uint_16(buf + 2, back->green);
+ png_save_uint_16(buf + 4, back->blue);
+ if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+ return;
+ }
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
+ }
+ else
+ {
+ if(back->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+ return;
+ }
+ png_save_uint_16(buf, back->gray);
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+/* write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_hIST;
+#endif
+ int i;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_hIST\n");
+ if (num_hist > (int)png_ptr->num_palette)
+ {
+ png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
+ png_ptr->num_palette);
+ png_warning(png_ptr, "Invalid number of histogram entries specified");
+ return;
+ }
+
+ png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+ for (i = 0; i < num_hist; i++)
+ {
+ png_save_uint_16(buf, hist[i]);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+ }
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
+ *
+ * The new_key is allocated to hold the corrected keyword and must be freed
+ * by the calling routine. This avoids problems with trying to write to
+ * static keywords without having to have duplicate copies of the strings.
+ */
+png_size_t /* PRIVATE */
+png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
+{
+ png_size_t key_len;
+ png_charp kp, dp;
+ int kflag;
+ int kwarn=0;
+
+ png_debug(1, "in png_check_keyword\n");
+ *new_key = NULL;
+
+ if (key == NULL || (key_len = png_strlen(key)) == 0)
+ {
+ png_warning(png_ptr, "zero length keyword");
+ return ((png_size_t)0);
+ }
+
+ png_debug1(2, "Keyword to be checked is '%s'\n", key);
+
+ *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
+ if (*new_key == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while procesing keyword");
+ return ((png_size_t)0);
+ }
+
+ /* Replace non-printing characters with a blank and print a warning */
+ for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
+ {
+ if ((png_byte)*kp < 0x20 ||
+ ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[40];
+
+ png_snprintf(msg, 40,
+ "invalid keyword character 0x%02X", (png_byte)*kp);
+ png_warning(png_ptr, msg);
+#else
+ png_warning(png_ptr, "invalid character in keyword");
+#endif
+ *dp = ' ';
+ }
+ else
+ {
+ *dp = *kp;
+ }
+ }
+ *dp = '\0';
+
+ /* Remove any trailing white space. */
+ kp = *new_key + key_len - 1;
+ if (*kp == ' ')
+ {
+ png_warning(png_ptr, "trailing spaces removed from keyword");
+
+ while (*kp == ' ')
+ {
+ *(kp--) = '\0';
+ key_len--;
+ }
+ }
+
+ /* Remove any leading white space. */
+ kp = *new_key;
+ if (*kp == ' ')
+ {
+ png_warning(png_ptr, "leading spaces removed from keyword");
+
+ while (*kp == ' ')
+ {
+ kp++;
+ key_len--;
+ }
+ }
+
+ png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
+
+ /* Remove multiple internal spaces. */
+ for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
+ {
+ if (*kp == ' ' && kflag == 0)
+ {
+ *(dp++) = *kp;
+ kflag = 1;
+ }
+ else if (*kp == ' ')
+ {
+ key_len--;
+ kwarn=1;
+ }
+ else
+ {
+ *(dp++) = *kp;
+ kflag = 0;
+ }
+ }
+ *dp = '\0';
+ if(kwarn)
+ png_warning(png_ptr, "extra interior spaces removed from keyword");
+
+ if (key_len == 0)
+ {
+ png_free(png_ptr, *new_key);
+ *new_key=NULL;
+ png_warning(png_ptr, "Zero length keyword");
+ }
+
+ if (key_len > 79)
+ {
+ png_warning(png_ptr, "keyword length must be 1 - 79 characters");
+ new_key[79] = '\0';
+ key_len = 79;
+ }
+
+ return (key_len);
+}
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+/* write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
+ png_size_t text_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tEXt;
+#endif
+ png_size_t key_len;
+ png_charp new_key;
+
+ png_debug(1, "in png_write_tEXt\n");
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in tEXt chunk");
+ return;
+ }
+
+ if (text == NULL || *text == '\0')
+ text_len = 0;
+ else
+ text_len = png_strlen(text);
+
+ /* make sure we include the 0 after the key */
+ png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1);
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+ if (text_len)
+ png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_key);
+}
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+/* write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
+ png_size_t text_len, int compression)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_zTXt;
+#endif
+ png_size_t key_len;
+ char buf[1];
+ png_charp new_key;
+ compression_state comp;
+
+ png_debug(1, "in png_write_zTXt\n");
+
+ comp.num_output_ptr = 0;
+ comp.max_output_ptr = 0;
+ comp.output_ptr = NULL;
+ comp.input = NULL;
+ comp.input_len = 0;
+
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in zTXt chunk");
+ return;
+ }
+
+ if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
+ {
+ png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
+ png_free(png_ptr, new_key);
+ return;
+ }
+
+ text_len = png_strlen(text);
+
+ /* compute the compressed data; do it now for the length */
+ text_len = png_text_compress(png_ptr, text, text_len, compression,
+ &comp);
+
+ /* write start of chunk */
+ png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32)
+ (key_len+text_len+2));
+ /* write key */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+ png_free(png_ptr, new_key);
+
+ buf[0] = (png_byte)compression;
+ /* write compression */
+ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+ /* write the compressed data */
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ /* close the chunk */
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+/* write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
+ png_charp lang, png_charp lang_key, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_iTXt;
+#endif
+ png_size_t lang_len, key_len, lang_key_len, text_len;
+ png_charp new_lang, new_key;
+ png_byte cbuf[2];
+ compression_state comp;
+
+ png_debug(1, "in png_write_iTXt\n");
+
+ comp.num_output_ptr = 0;
+ comp.max_output_ptr = 0;
+ comp.output_ptr = NULL;
+ comp.input = NULL;
+
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in iTXt chunk");
+ return;
+ }
+ if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
+ {
+ png_warning(png_ptr, "Empty language field in iTXt chunk");
+ new_lang = NULL;
+ lang_len = 0;
+ }
+
+ if (lang_key == NULL)
+ lang_key_len = 0;
+ else
+ lang_key_len = png_strlen(lang_key);
+
+ if (text == NULL)
+ text_len = 0;
+ else
+ text_len = png_strlen(text);
+
+ /* compute the compressed data; do it now for the length */
+ text_len = png_text_compress(png_ptr, text, text_len, compression-2,
+ &comp);
+
+
+ /* make sure we include the compression flag, the compression byte,
+ * and the NULs after the key, lang, and lang_key parts */
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
+ (png_uint_32)(
+ 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+ + key_len
+ + lang_len
+ + lang_key_len
+ + text_len));
+
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+
+ /* set the compression flag */
+ if (compression == PNG_ITXT_COMPRESSION_NONE || \
+ compression == PNG_TEXT_COMPRESSION_NONE)
+ cbuf[0] = 0;
+ else /* compression == PNG_ITXT_COMPRESSION_zTXt */
+ cbuf[0] = 1;
+ /* set the compression method */
+ cbuf[1] = 0;
+ png_write_chunk_data(png_ptr, cbuf, 2);
+
+ cbuf[0] = 0;
+ png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1);
+ png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1);
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_key);
+ if (new_lang)
+ png_free(png_ptr, new_lang);
+}
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+/* write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+ int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_oFFs;
+#endif
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_oFFs\n");
+ if (unit_type >= PNG_OFFSET_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+ png_save_int_32(buf, x_offset);
+ png_save_int_32(buf + 4, y_offset);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+}
+#endif
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+/* write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
+ png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_pCAL;
+#endif
+ png_size_t purpose_len, units_len, total_len;
+ png_uint_32p params_len;
+ png_byte buf[10];
+ png_charp new_purpose;
+ int i;
+
+ png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
+ if (type >= PNG_EQUATION_LAST)
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+ purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
+ png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
+ units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
+ png_debug1(3, "pCAL units length = %d\n", (int)units_len);
+ total_len = purpose_len + units_len + 10;
+
+ params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
+ *png_sizeof(png_uint_32)));
+
+ /* Find the length of each parameter, making sure we don't count the
+ null terminator for the last parameter. */
+ for (i = 0; i < nparams; i++)
+ {
+ params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+ png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
+ total_len += (png_size_t)params_len[i];
+ }
+
+ png_debug1(3, "pCAL total length = %d\n", (int)total_len);
+ png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
+ png_save_int_32(buf, X0);
+ png_save_int_32(buf + 4, X1);
+ buf[8] = (png_byte)type;
+ buf[9] = (png_byte)nparams;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+ png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
+
+ png_free(png_ptr, new_purpose);
+
+ for (i = 0; i < nparams; i++)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)params[i],
+ (png_size_t)params_len[i]);
+ }
+
+ png_free(png_ptr, params_len);
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+/* write the sCAL chunk */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+void /* PRIVATE */
+png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sCAL;
+#endif
+ char buf[64];
+ png_size_t total_len;
+
+ png_debug(1, "in png_write_sCAL\n");
+
+ buf[0] = (char)unit;
+#if defined(_WIN32_WCE)
+/* sprintf() function is not supported on WindowsCE */
+ {
+ wchar_t wc_buf[32];
+ size_t wc_len;
+ swprintf(wc_buf, TEXT("%12.12e"), width);
+ wc_len = wcslen(wc_buf);
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL);
+ total_len = wc_len + 2;
+ swprintf(wc_buf, TEXT("%12.12e"), height);
+ wc_len = wcslen(wc_buf);
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
+ NULL, NULL);
+ total_len += wc_len;
+ }
+#else
+ png_snprintf(buf + 1, 63, "%12.12e", width);
+ total_len = 1 + png_strlen(buf + 1) + 1;
+ png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
+ total_len += png_strlen(buf + total_len);
+#endif
+
+ png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
+ png_write_chunk(png_ptr, png_sCAL, (png_bytep)buf, total_len);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
+ png_charp height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sCAL;
+#endif
+ png_byte buf[64];
+ png_size_t wlen, hlen, total_len;
+
+ png_debug(1, "in png_write_sCAL_s\n");
+
+ wlen = png_strlen(width);
+ hlen = png_strlen(height);
+ total_len = wlen + hlen + 2;
+ if (total_len > 64)
+ {
+ png_warning(png_ptr, "Can't write sCAL (buffer too small)");
+ return;
+ }
+
+ buf[0] = (png_byte)unit;
+ png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */
+ png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */
+
+ png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
+ png_write_chunk(png_ptr, png_sCAL, buf, total_len);
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+/* write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
+ png_uint_32 y_pixels_per_unit,
+ int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_pHYs;
+#endif
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_pHYs\n");
+ if (unit_type >= PNG_RESOLUTION_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+ png_save_uint_32(buf, x_pixels_per_unit);
+ png_save_uint_32(buf + 4, y_pixels_per_unit);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* Write the tIME chunk. Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structp png_ptr, png_timep mod_time)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tIME;
+#endif
+ png_byte buf[7];
+
+ png_debug(1, "in png_write_tIME\n");
+ if (mod_time->month > 12 || mod_time->month < 1 ||
+ mod_time->day > 31 || mod_time->day < 1 ||
+ mod_time->hour > 23 || mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Invalid time specified for tIME chunk");
+ return;
+ }
+
+ png_save_uint_16(buf, mod_time->year);
+ buf[2] = mod_time->month;
+ buf[3] = mod_time->day;
+ buf[4] = mod_time->hour;
+ buf[5] = mod_time->minute;
+ buf[6] = mod_time->second;
+
+ png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+void /* PRIVATE */
+png_write_acTL(png_structp png_ptr,
+ png_uint_32 num_frames, png_uint_32 num_plays)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_acTL;
+#endif
+ png_byte data[16];
+
+ png_debug(1, "in png_write_acTL\n");
+
+ png_ptr->num_frames_to_write = num_frames;
+
+ if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
+ num_frames--;
+
+ png_save_uint_32(data, num_frames);
+ png_save_uint_32(data + 4, num_plays);
+
+ png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8);
+}
+
+void /* PRIVATE */
+png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+ png_uint_32 x_offset, png_uint_32 y_offset,
+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
+ png_byte blend_op)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_fcTL;
+#endif
+ png_byte data[26];
+
+ png_debug(1, "in png_write_fcTL\n");
+
+ if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
+ png_error(png_ptr, "x and/or y offset for the first frame aren't 0\n");
+ if (png_ptr->num_frames_written == 0 &&
+ (width != png_ptr->first_frame_width ||
+ height != png_ptr->first_frame_height))
+ png_error(png_ptr, "width and/or height in the first frame's fcTL "
+ "don't match the ones in IHDR\n");
+
+ /* more error checking */
+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
+ delay_num, delay_den, dispose_op, blend_op);
+
+ png_save_uint_32(data, png_ptr->next_seq_num);
+ png_save_uint_32(data + 4, width);
+ png_save_uint_32(data + 8, height);
+ png_save_uint_32(data + 12, x_offset);
+ png_save_uint_32(data + 16, y_offset);
+ png_save_uint_16(data + 20, delay_num);
+ png_save_uint_16(data + 22, delay_den);
+ data[24] = dispose_op;
+ data[25] = blend_op;
+
+ png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26);
+
+ png_ptr->next_seq_num++;
+}
+#endif /* PNG_WRITE_APNG_SUPPORTED */
+
+/* initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+#endif
+
+ png_size_t buf_size;
+
+ png_debug(1, "in png_write_start_row\n");
+ buf_size = (png_size_t)(PNG_ROWBYTES(
+ png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1);
+
+ /* set up row buffer */
+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+ png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+#ifndef PNG_NO_WRITE_FILTERING
+ /* set up filtering buffer, if using this filter */
+ if (png_ptr->do_filter & PNG_FILTER_SUB)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ /* We only need to keep the previous row if we are using one of these. */
+ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+ {
+ /* set up previous row buffer */
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+ png_memset(png_ptr->prev_row, 0, buf_size);
+
+ if (png_ptr->do_filter & PNG_FILTER_UP)
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_AVG)
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_PAETH)
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+#endif /* PNG_NO_WRITE_FILTERING */
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* if interlaced, we need to set up width and height of pass */
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+ png_pass_start[0]) / png_pass_inc[0];
+ }
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ }
+ else
+#endif
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+}
+
+/* Internal use only. Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+#endif
+
+ int ret;
+
+ png_debug(1, "in png_write_finish_row\n");
+ /* next row */
+ png_ptr->row_number++;
+
+ /* see if we are done */
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* if interlaced, go to next pass */
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ if (png_ptr->transformations & PNG_INTERLACE)
+ {
+ png_ptr->pass++;
+ }
+ else
+ {
+ /* loop until we find a non-zero width or height pass */
+ do
+ {
+ png_ptr->pass++;
+ if (png_ptr->pass >= 7)
+ break;
+ png_ptr->usr_width = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+ } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+ }
+
+ /* reset the row above the image for the next pass */
+ if (png_ptr->pass < 7)
+ {
+ if (png_ptr->prev_row != NULL)
+ png_memset(png_ptr->prev_row, 0,
+ (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+ png_ptr->usr_bit_depth,png_ptr->width))+1);
+ return;
+ }
+ }
+#endif
+
+ /* if we get here, we've just written the last row, so we need
+ to flush the compressor */
+ do
+ {
+ /* tell the compressor we are done */
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
+ /* check for an error */
+ if (ret == Z_OK)
+ {
+ /* check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ else if (ret != Z_STREAM_END)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ } while (ret != Z_STREAM_END);
+
+ /* write any extra space */
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+ {
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out);
+ }
+
+ deflateReset(&png_ptr->zstream);
+ png_ptr->zstream.data_type = Z_BINARY;
+}
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass. As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+ png_debug(1, "in png_do_write_interlace\n");
+ /* we don't have to do anything on the last pass (6) */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL && pass < 6)
+#else
+ if (pass < 6)
+#endif
+ {
+ /* each pixel depth is handled separately */
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ d = 0;
+ shift = 7;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 3);
+ value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 7;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift--;
+
+ }
+ if (shift != 7)
+ *dp = (png_byte)d;
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 6;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 2);
+ value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift -= 2;
+ }
+ if (shift != 6)
+ *dp = (png_byte)d;
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 4;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 1);
+ value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift -= 4;
+ }
+ if (shift != 4)
+ *dp = (png_byte)d;
+ break;
+ }
+ default:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ png_size_t pixel_bytes;
+
+ /* start at the beginning */
+ dp = row;
+ /* find out how many bytes each pixel takes up */
+ pixel_bytes = (row_info->pixel_depth >> 3);
+ /* loop through the row, only looking at the pixels that
+ matter */
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ /* find out where the original pixel is */
+ sp = row + (png_size_t)i * pixel_bytes;
+ /* move the pixel */
+ if (dp != sp)
+ png_memcpy(dp, sp, pixel_bytes);
+ /* next pixel */
+ dp += pixel_bytes;
+ }
+ break;
+ }
+ }
+ /* set new row width */
+ row_info->width = (row_info->width +
+ png_pass_inc[pass] - 1 -
+ png_pass_start[pass]) /
+ png_pass_inc[pass];
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
+{
+ png_bytep best_row;
+#ifndef PNG_NO_WRITE_FILTER
+ png_bytep prev_row, row_buf;
+ png_uint_32 mins, bpp;
+ png_byte filter_to_do = png_ptr->do_filter;
+ png_uint_32 row_bytes = row_info->rowbytes;
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ int num_p_filters = (int)png_ptr->num_prev_filters;
+#endif
+
+ png_debug(1, "in png_write_find_filter\n");
+ /* find out how many bytes offset each pixel is */
+ bpp = (row_info->pixel_depth + 7) >> 3;
+
+ prev_row = png_ptr->prev_row;
+#endif
+ best_row = png_ptr->row_buf;
+#ifndef PNG_NO_WRITE_FILTER
+ row_buf = best_row;
+ mins = PNG_MAXSUM;
+
+ /* The prediction method we use is to find which method provides the
+ * smallest value when summing the absolute values of the distances
+ * from zero, using anything >= 128 as negative numbers. This is known
+ * as the "minimum sum of absolute differences" heuristic. Other
+ * heuristics are the "weighted minimum sum of absolute differences"
+ * (experimental and can in theory improve compression), and the "zlib
+ * predictive" method (not implemented yet), which does test compressions
+ * of lines using different filter methods, and then chooses the
+ * (series of) filter(s) that give minimum compressed data size (VERY
+ * computationally expensive).
+ *
+ * GRR 980525: consider also
+ * (1) minimum sum of absolute differences from running average (i.e.,
+ * keep running sum of non-absolute differences & count of bytes)
+ * [track dispersion, too? restart average if dispersion too large?]
+ * (1b) minimum sum of absolute differences from sliding average, probably
+ * with window size <= deflate window (usually 32K)
+ * (2) minimum sum of squared differences from zero or running average
+ * (i.e., ~ root-mean-square approach)
+ */
+
+
+ /* We don't need to test the 'no filter' case if this is the only filter
+ * that has been chosen, as it doesn't actually do anything to the data.
+ */
+ if ((filter_to_do & PNG_FILTER_NONE) &&
+ filter_to_do != PNG_FILTER_NONE)
+ {
+ png_bytep rp;
+ png_uint_32 sum = 0;
+ png_uint_32 i;
+ int v;
+
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ {
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ png_uint_32 sumhi, sumlo;
+ int j;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+ /* Reduce the sum if we match any of the previous rows */
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ /* Factor in the cost of this filter (this is here for completeness,
+ * but it makes no sense to have a "cost" for the NONE filter, as
+ * it has the minimum possible computational cost - none).
+ */
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+ mins = sum;
+ }
+
+ /* sub filter */
+ if (filter_to_do == PNG_FILTER_SUB)
+ /* it's the only filter so no testing is needed */
+ {
+ png_bytep rp, lp, dp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+ best_row = png_ptr->sub_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_SUB)
+ {
+ png_bytep rp, dp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ /* We temporarily increase the "minimum sum" by the factor we
+ * would reduce the sum of this filter, so that we can do the
+ * early exit comparison without scaling the sum each time.
+ */
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->sub_row;
+ }
+ }
+
+ /* up filter */
+ if (filter_to_do == PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+ best_row = png_ptr->up_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->up_row;
+ }
+ }
+
+ /* avg filter */
+ if (filter_to_do == PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+ best_row = png_ptr->avg_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ =
+ (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->avg_row;
+ }
+ }
+
+ /* Paeth filter */
+ if (filter_to_do == PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+ best_row = png_ptr->paeth_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+ p = b - c;
+ pc = a - c;
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+ p = a + b - c;
+ pa = abs(p - a);
+ pb = abs(p - b);
+ pc = abs(p - c);
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+#endif /* PNG_SLOW_PAETH */
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ best_row = png_ptr->paeth_row;
+ }
+ }
+#endif /* PNG_NO_WRITE_FILTER */
+ /* Do the actual writing of the filtered row data from the chosen filter. */
+
+ png_write_filtered_row(png_ptr, best_row);
+
+#ifndef PNG_NO_WRITE_FILTER
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ /* Save the type of filter we picked this time for future calculations */
+ if (png_ptr->num_prev_filters > 0)
+ {
+ int j;
+ for (j = 1; j < num_p_filters; j++)
+ {
+ png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+ }
+ png_ptr->prev_filters[j] = best_row[0];
+ }
+#endif
+#endif /* PNG_NO_WRITE_FILTER */
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+void /* PRIVATE */
+png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
+{
+ png_debug(1, "in png_write_filtered_row\n");
+ png_debug1(2, "filter = %d\n", filtered_row[0]);
+ /* set up the zlib input buffer */
+
+ png_ptr->zstream.next_in = filtered_row;
+ png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+ /* repeat until we have compressed all the data */
+ do
+ {
+ int ret; /* return of zlib */
+
+ /* compress the data */
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+ /* check for compression errors */
+ if (ret != Z_OK)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+
+ /* see if it is time to write another IDAT */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ /* repeat until all data has been compressed */
+ } while (png_ptr->zstream.avail_in);
+
+ /* swap the current and previous rows */
+ if (png_ptr->prev_row != NULL)
+ {
+ png_bytep tptr;
+
+ tptr = png_ptr->prev_row;
+ png_ptr->prev_row = png_ptr->row_buf;
+ png_ptr->row_buf = tptr;
+ }
+
+ /* finish row - updates counters and flushes zlib if last row */
+ png_write_finish_row(png_ptr);
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ png_ptr->flush_rows++;
+
+ if (png_ptr->flush_dist > 0 &&
+ png_ptr->flush_rows >= png_ptr->flush_dist)
+ {
+ png_write_flush(png_ptr);
+ }
+#endif
+}
+
+#if defined(PNG_WRITE_APNG_SUPPORTED)
+void /* PRIVATE */
+png_write_reset(png_structp png_ptr)
+{
+ png_ptr->row_number = 0;
+ png_ptr->pass = 0;
+ png_ptr->mode &= ~PNG_HAVE_IDAT;
+}
+
+void /* PRIVATE */
+png_write_reinit(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 width, png_uint_32 height)
+{
+ if (png_ptr->num_frames_written == 0 &&
+ (width != png_ptr->first_frame_width ||
+ height != png_ptr->first_frame_height))
+ png_error(png_ptr, "width and/or height in the first frame's fcTL "
+ "don't match the ones in IHDR\n");
+ if (width > png_ptr->first_frame_width ||
+ height > png_ptr->first_frame_height)
+ png_error(png_ptr, "width and/or height for a frame greater than"
+ "the ones in IHDR");
+
+ png_set_IHDR(png_ptr, info_ptr, width, height,
+ info_ptr->bit_depth, info_ptr->color_type,
+ info_ptr->interlace_type, info_ptr->compression_type,
+ info_ptr->filter_type);
+
+ png_ptr->width = width;
+ png_ptr->height = height;
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+ png_ptr->usr_width = png_ptr->width;
+}
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/kernel/kls_pnm/Makefile.am b/kernel/kls_pnm/Makefile.am
new file mode 100644
index 0000000..ddc0486
--- /dev/null
+++ b/kernel/kls_pnm/Makefile.am
@@ -0,0 +1,11 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_pnm.la
+
+libkls_pnm_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_pnm_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pnm_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_PNM \ No newline at end of file
diff --git a/kernel/kls_pnm/fmt_codec_pnm.cpp b/kernel/kls_pnm/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..00edbfb
--- /dev/null
+++ b/kernel/kls_pnm/fmt_codec_pnm.cpp
@@ -0,0 +1,1469 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pnm/fmt_codec_pnm_defs.h b/kernel/kls_pnm/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_pnm/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_psd/Makefile.am b/kernel/kls_psd/Makefile.am
new file mode 100644
index 0000000..82132ab
--- /dev/null
+++ b/kernel/kls_psd/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_psd.la
+
+libkls_psd_la_SOURCES = fmt_codec_psd.cpp fmt_codec_psd_defs.h
+
+libkls_psd_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_psd_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_psd/fmt_codec_psd.cpp b/kernel/kls_psd/fmt_codec_psd.cpp
new file mode 100644
index 0000000..dad3863
--- /dev/null
+++ b/kernel/kls_psd/fmt_codec_psd.cpp
@@ -0,0 +1,394 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_psd_defs.h"
+#include "fmt_codec_psd.h"
+
+#include "../xpm/codec_psd.xpm"
+
+/*
+ *
+ * Adobe's Photoshop is probably the fullest featured and most highly
+ * respected commercial image-processing bitmap manipulation program in
+ * the PC and Macintosh worlds. Its wide distribution
+ * has meant that image data is often left in PSD
+ * format files and may persist in this form after the original image
+ * data is long gone.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.8.1";
+ o->name = "Adobe Photoshop PSD";
+ o->filter = "*.psd ";
+ o->config = "";
+ o->mime = "\x0038\x0042\x0050\x0053\x0001";
+ o->mimetype = "image/psd;image/x-vnd.adobe.photoshop";
+ o->pixmap = codec_psd;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ layer = -1;
+
+ u32 ident;
+ u16 ver;
+
+ if(!frs.be_getlong(&ident))
+ return SQE_R_BADFILE;
+
+ if(ident != 0x38425053)
+ return SQE_R_NOTSUPPORTED;
+
+ if(!frs.be_getshort(&ver))
+ return SQE_R_BADFILE;
+
+ if(ver != 1)
+ return SQE_R_BADFILE;
+
+ last = 0;
+ L = 0;
+
+ s8 dummy[6];
+ if(!frs.readK(dummy, 6)) return SQE_R_BADFILE;
+
+ if(!frs.be_getshort(&channels))
+ return SQE_R_BADFILE;
+
+ if(!frs.be_getlong(&height))
+ return SQE_R_BADFILE;
+
+ if(!frs.be_getlong(&width))
+ return SQE_R_BADFILE;
+
+ if(!frs.be_getshort(&depth))
+ return SQE_R_BADFILE;
+
+ if(!frs.be_getshort(&mode))
+ return SQE_R_BADFILE;
+
+ if(depth != 8)
+ return SQE_R_NOTSUPPORTED;
+
+ if(mode != PSD_RGB && mode != PSD_CMYK && mode != PSD_INDEXED && mode != PSD_GRAYSCALE)
+ return SQE_R_NOTSUPPORTED;
+
+ if(mode == PSD_RGB && channels != 3 && channels != 4)
+ return SQE_R_NOTSUPPORTED;
+
+ if(mode == PSD_CMYK && channels != 4 && channels != 5)
+ return SQE_R_NOTSUPPORTED;
+
+ if(mode == PSD_INDEXED && channels != 1)
+ return SQE_R_NOTSUPPORTED;
+
+ u32 data_count;
+
+ if(!frs.be_getlong(&data_count))
+ return SQE_R_BADFILE;
+
+ if(data_count)
+ {
+ if(!frs.readK(pal, 256 * sizeof(RGB))) return SQE_R_BADFILE;
+ }
+
+ if(!frs.be_getlong(&data_count))
+ return SQE_R_BADFILE;
+
+ if(data_count)
+ frs.seekg(data_count, ios::cur);
+
+ if(!frs.be_getlong(&data_count))
+ return SQE_R_BADFILE;
+
+ if(data_count)
+ frs.seekg(data_count, ios::cur);
+
+ // find out if the data is compressed
+ // 0: no compressiod
+ // 1: RLE compressed
+
+ if(!frs.be_getshort(&compression))
+ return SQE_R_BADFILE;
+
+ if(compression != 1 && compression != 0)
+ return SQE_R_NOTSUPPORTED;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ image.hasalpha = (mode == PSD_RGB) ? true : ((channels == 5) ? true : false);
+ image.passes = (channels == 5) ? 4 : channels;
+ image.h = height;
+ image.w = width;
+
+ if(compression)
+ {
+ u16 b[height * channels];
+
+ if(!frs.readK(b, 2 * height * channels)) return SQE_R_BADFILE;
+ }
+
+ std::string type;
+
+ switch(mode)
+ {
+ case PSD_RGB:
+ type = "RGB";
+ image.bpp = 24;
+ break;
+
+ case PSD_CMYK:
+ type = "CMYK";
+ image.bpp = (channels == 5) ? 32 : 24;
+ break;
+
+ case PSD_INDEXED:
+ type = "Color indexed";
+ image.bpp = 8;
+ break;
+
+ case PSD_GRAYSCALE:
+ type = "Grayscale";
+ image.bpp = 8;
+ break;
+ }
+
+ last = (RGBA **)calloc(height, sizeof(RGBA*));
+
+ if(!last)
+ return SQE_R_NOMEMORY;
+
+ const s32 S = width * sizeof(RGBA);
+
+ for(u32 i = 0;i < height;i++)
+ {
+ last[i] = (RGBA*)0;
+ }
+
+ for(u32 i = 0;i < height;i++)
+ {
+ last[i] = (RGBA*)malloc(S);
+
+ if(!last[i])
+ return SQE_R_NOMEMORY;
+
+ memset(last[i], 255, S);
+ }
+
+ line = -1;
+
+ L = (u8*)calloc(width, 1);
+
+ if(!L)
+ return SQE_R_NOMEMORY;
+
+ image.compression = ((compression) ? "RLE" : "-");
+ image.colorspace = type;
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ layer++;
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u8 c, value, *p;
+ s32 count = 0;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ memcpy(scan, last[line], im->w * sizeof(RGBA));
+
+ if(compression)
+ {
+ while(count < im->w)
+ {
+ if(!frs.readK(&c, 1)) return SQE_R_BADFILE;
+
+ if(c == 128)
+ {} // do nothing
+ else if(c > 128)
+ {
+ c ^= 0xff;
+ c += 2;
+
+ if(!frs.readK(&value, 1)) return SQE_R_BADFILE;
+
+ for(s32 i = count; i < count+c;i++)
+ {
+ p = (u8*)(scan+i);
+ *(p+layer) = value;
+ }
+
+ count += c;
+ }
+ else if(c < 128)
+ {
+ c++;
+
+ for(s32 i = count; i < count+c;i++)
+ {
+ if(!frs.readK(&value, 1)) return SQE_R_BADFILE;
+
+ p = (u8*)(scan+i);
+ *(p+layer) = value;
+ }
+
+ count += c;
+ }
+ }
+ }
+ else
+ {
+ if(!frs.readK(L, width)) return SQE_R_BADFILE;
+
+ for(u32 i = 0;i < width;i++)
+ {
+ p = (u8*)(scan+i);
+ *(p+layer) = L[i];
+ }
+ }
+
+ memcpy(last[line], scan, im->w * sizeof(RGBA));
+
+ if(layer == im->passes-1)
+ {
+ if(mode == PSD_CMYK)
+ {
+ for(s32 i = 0;i < im->w;i++)
+ {
+ scan[i].r = (scan[i].r * scan[i].a) >> 8;
+ scan[i].g = (scan[i].g * scan[i].a) >> 8;
+ scan[i].b = (scan[i].b * scan[i].a) >> 8;
+
+ if(channels == 4)
+ scan[i].a = 255;
+ }
+ }
+ else if(mode == PSD_INDEXED)
+ {
+ u8 r;
+ const s32 z1 = 768/3;
+ const s32 z2 = z1 << 1;
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ u8 *p = (u8*)pal;
+ r = scan[i].r;
+
+ (scan+i)->r = *(p+r);
+ (scan+i)->g = *(p+r+z1);
+ (scan+i)->b = *(p+r+z2);
+ scan[i].a = 255;
+ }
+ }
+ else if(mode == PSD_GRAYSCALE)
+ {
+ u8 v;
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ v = scan[i].r;
+
+ (scan+i)->r = v;
+ (scan+i)->g = v;
+ (scan+i)->b = v;
+ scan[i].a = 255;
+ }
+ }
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ if(last)
+ {
+ for(u32 i = 0;i < height;i++)
+ {
+ if(last[i])
+ free(last[i]);
+ }
+
+ free(last);
+ }
+
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ if(L)
+ free(L);
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_psd/fmt_codec_psd_defs.h b/kernel/kls_psd/fmt_codec_psd_defs.h
new file mode 100644
index 0000000..aa6f3dd
--- /dev/null
+++ b/kernel/kls_psd/fmt_codec_psd_defs.h
@@ -0,0 +1,43 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_psd
+#define KSQUIRREL_READ_IMAGE_psd
+
+// 0: Bitmap
+// 1: Grayscale
+// 2: Indexed color
+// 3: RGB color
+// 4: CMYK color
+// 7: Multichannel
+// 8: Duotone
+// 9: Lab color
+
+#define PSD_BITMAP 0
+#define PSD_GRAYSCALE 1
+#define PSD_INDEXED 2
+#define PSD_RGB 3
+#define PSD_CMYK 4
+#define PSD_MULTICHANNEL 7
+#define PSD_DUOTONE 8
+#define PSD_LAB 9
+
+#endif
diff --git a/kernel/kls_psp/Makefile.am b/kernel/kls_psp/Makefile.am
new file mode 100644
index 0000000..d9ae202
--- /dev/null
+++ b/kernel/kls_psp/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_psp.la
+
+libkls_psp_la_SOURCES = fmt_codec_psp.cpp fmt_codec_psp_defs.h
+
+libkls_psp_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_psp_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_psp/fmt_codec_psp.cpp b/kernel/kls_psp/fmt_codec_psp.cpp
new file mode 100644
index 0000000..e77caa4
--- /dev/null
+++ b/kernel/kls_psp/fmt_codec_psp.cpp
@@ -0,0 +1,635 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <cstdlib>
+#include <stdio.h>
+#include <string.h>
+#include <algorithm>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_psp_defs.h"
+#include "fmt_codec_psp.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_psp.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "PaintShop Pro";
+ o->filter = "*.psp ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-psp";
+ o->pixmap = codec_psp;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+/************** Utility functions from DevIL *********************/
+
+//-----------------------------------------------------------------------------
+//
+// ImageLib Sources
+// Copyright (C) 2000-2002 by Denton Woods
+// Last modified: 05/04/2002 <--Y2K Compliant! =]
+//
+// Filename: src-IL/src/il_psp.c
+//
+// Description: Reads a Paint Shop Pro file.
+//
+//-----------------------------------------------------------------------------
+
+
+bool fmt_codec::iGetPspHead()
+{
+ if(!frs.readK(Header.FileSig, 32))
+ return false;
+
+ if(!frs.readK(&Header.MajorVersion, sizeof(Header.MajorVersion)))
+ return false;
+
+ if(!frs.readK(&Header.MinorVersion, sizeof(Header.MinorVersion)))
+ return false;
+
+ return true;
+}
+
+bool fmt_codec::iCheckPsp()
+{
+ if (strcmp(Header.FileSig, "Paint Shop Pro Image File\n\x1a")) // "i"
+ return false;
+ if (Header.MajorVersion < 3 || Header.MajorVersion > 5)
+ return false;
+ if (Header.MinorVersion != 0)
+ return false;
+
+ return true;
+}
+
+bool fmt_codec::ReadGenAttributes()
+{
+ BLOCKHEAD AttHead;
+ ILint Padding;
+ ILuint ChunkLen;
+
+ if(!frs.readK(&AttHead, sizeof(AttHead)))
+ return false;
+
+ if (AttHead.HeadID[0] != 0x7E || AttHead.HeadID[1] != 0x42 || AttHead.HeadID[2] != 0x4B || AttHead.HeadID[3] != 0x00)
+ return false;
+
+ if (AttHead.BlockID != PSP_IMAGE_BLOCK)
+ return false;
+
+ if(!frs.readK(&ChunkLen, sizeof(ChunkLen)))
+ return false;
+
+ if (Header.MajorVersion != 3)
+ ChunkLen -= 4;
+
+ if (!frs.readK(&AttChunk, std::min(sizeof(AttChunk), size_t(ChunkLen))))
+ return false;
+
+ // Can have new entries in newer versions of the spec (4.0).
+ Padding = (ChunkLen) - sizeof(AttChunk);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+
+ // @TODO: Anything but 24 not supported yet...
+ if (AttChunk.BitDepth != 24 && AttChunk.BitDepth != 8)
+ return false;
+
+ // @TODO; Add support for compression...
+ if (AttChunk.Compression != PSP_COMP_NONE && AttChunk.Compression != PSP_COMP_RLE)
+ return false;
+
+ // @TODO: Check more things in the general attributes chunk here.
+ return true;
+}
+
+bool fmt_codec::ParseChunks()
+{
+ BLOCKHEAD Block;
+ size_t Pos;
+
+ do {
+ if (!frs.readK(&Block, sizeof(Block)))
+ return true;
+
+ if (Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00)
+ return true;
+
+ Pos = frs.tellg();
+
+ switch (Block.BlockID)
+ {
+ case PSP_LAYER_START_BLOCK:
+ if (!ReadLayerBlock())
+ return false;
+ break;
+
+ case PSP_ALPHA_BANK_BLOCK:
+ if (!ReadAlphaBlock())
+ return false;
+ break;
+
+ case PSP_COLOR_BLOCK:
+ if (!ReadPalette())
+ return false;
+ break;
+ }
+
+ // Skip to next block just in case we didn't read the entire block.
+ frs.seekg(Pos + Block.BlockLen, ios::beg);
+
+ }
+ while (1);
+
+ return true;
+}
+
+bool fmt_codec::ReadLayerBlock()
+{
+ BLOCKHEAD Block;
+ LAYERINFO_CHUNK LayerInfo;
+ LAYERBITMAP_CHUNK Bitmap;
+ ILuint ChunkSize, Padding, i;
+ ILushort NumChars;
+
+ // Layer sub-block header
+ if (!frs.readK(&Block, sizeof(Block)))
+ return false;
+
+ if(Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00)
+ return false;
+
+ if (Block.BlockID != PSP_LAYER_BLOCK)
+ return false;
+
+ if (Header.MajorVersion == 3)
+ {
+ frs.seekg(256, ios::cur); // We don't care about the name of the layer.
+ frs.readK(&LayerInfo, sizeof(LayerInfo));
+
+ if(!frs.readK(&Bitmap, sizeof(Bitmap)))
+ return false;
+ }
+ else
+ { // Header.MajorVersion >= 4
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&NumChars, sizeof(NumChars));
+ frs.seekg(NumChars, ios::cur); // We don't care about the layer's name.
+
+ ChunkSize -= (2 + 4 + NumChars);
+
+ if (!frs.readK(&LayerInfo, std::min(sizeof(LayerInfo), size_t(ChunkSize))))
+ return false;
+
+ // Can have new entries in newer versions of the spec (5.0).
+ Padding = (ChunkSize) - sizeof(LayerInfo);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+
+ if (!frs.readK(&Bitmap, sizeof(Bitmap)))
+ return false;
+
+ Padding = (ChunkSize - 4) - sizeof(Bitmap);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+
+ Channels = new ILubyte* [Bitmap.NumChannels];
+
+ if (!Channels)
+ return false;
+
+ NumChannels = Bitmap.NumChannels;
+
+ for (i = 0; i < NumChannels; i++)
+ Channels[i] = 0;
+
+ for (i = 0; i < NumChannels; i++)
+ {
+ Channels[i] = GetChannel();
+
+ if(!Channels[i])
+ return false;
+ }
+
+ return true;
+}
+
+bool fmt_codec::ReadAlphaBlock()
+{
+ BLOCKHEAD Block;
+ ALPHAINFO_CHUNK AlphaInfo;
+ ALPHA_CHUNK AlphaChunk;
+ ILushort NumAlpha, StringSize;
+ ILuint ChunkSize, Padding;
+
+ if (Header.MajorVersion == 3) {
+ frs.readK(&NumAlpha, sizeof(NumAlpha));
+ }
+ else {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&NumAlpha, sizeof(NumAlpha));
+
+ Padding = (ChunkSize - 4 - 2);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+
+ // Alpha channel header
+ if (!frs.readK(&Block, sizeof(Block)))
+ return false;
+
+ if (Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
+ Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
+ return false;
+ }
+ if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK)
+ return false;
+
+ if (Header.MajorVersion >= 4)
+ {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&StringSize, sizeof(StringSize));
+
+ frs.seekg(StringSize, ios::cur);
+
+ if (!frs.readK(&AlphaInfo, sizeof(AlphaInfo)))
+ return false;
+
+ Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo));
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+
+ if (!frs.readK(&AlphaChunk, sizeof(AlphaChunk)))
+ return false;
+
+ Padding = (ChunkSize - 4 - sizeof(AlphaChunk));
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+ else {
+ frs.seekg(256, ios::cur);
+ frs.readK(&AlphaInfo, sizeof(AlphaInfo));
+
+ if(!frs.readK(&AlphaChunk, sizeof(AlphaChunk)))
+ return false;
+ }
+
+ Alpha = GetChannel();
+
+ if (!Alpha)
+ return false;
+
+ return true;
+}
+
+ILubyte *fmt_codec::GetChannel()
+{
+ BLOCKHEAD Block;
+ CHANNEL_CHUNK Channel;
+ ILubyte *CompData = 0, *Data = 0;
+ ILuint ChunkSize, Padding;
+
+ if (!frs.readK(&Block, sizeof(Block)))
+ return 0;
+
+ if (Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00)
+ return 0;
+
+ if (Block.BlockID != PSP_CHANNEL_BLOCK)
+ return 0;
+
+ if (Header.MajorVersion >= 4)
+ {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+
+ if (!frs.readK(&Channel, sizeof(Channel)))
+ return 0;
+
+ Padding = (ChunkSize - 4) - sizeof(Channel);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+ else
+ {
+ if (!frs.readK(&Channel, sizeof(Channel)))
+ return 0;
+ }
+
+ CompData = new ILubyte [Channel.CompLen];
+
+ if (!CompData)
+ return 0;
+
+ if (!frs.readK(CompData, Channel.CompLen))
+ {
+ delete CompData;
+ return 0;
+ }
+
+ if(AttChunk.Compression != PSP_COMP_NONE)
+ {
+ Data = new ILubyte [AttChunk.Width * AttChunk.Height];
+
+ if (!Data)
+ {
+ delete CompData;
+ return 0;
+ }
+ }
+
+ switch (AttChunk.Compression)
+ {
+ case PSP_COMP_NONE:
+ return CompData;
+
+ case PSP_COMP_RLE:
+ if (!UncompRLE(CompData, Data, Channel.CompLen))
+ {
+ delete Data;
+ delete CompData;
+ return 0;
+ }
+ break;
+
+ default:
+ delete Data;
+ delete CompData;
+ return 0;
+ }
+
+ delete CompData;
+
+ return Data;
+}
+
+bool fmt_codec::UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen)
+{
+ ILubyte Run, Colour;
+ ILint i, Count;
+
+ for (i = 0, Count = 0; i < (ILint)CompLen; ) {
+ Run = *CompData++;
+ i++;
+ if (Run > 128) {
+ Run -= 128;
+ Colour = *CompData++;
+ i++;
+ memset(Data, Colour, Run);
+ }
+ else {
+ memcpy(Data, CompData, Run);
+ CompData += Run;
+ i += Run;
+ }
+ Data += Run;
+ Count += Run;
+ }
+
+ return true;
+}
+
+bool fmt_codec::ReadPalette()
+{
+ ILuint ChunkSize, PalCount, Padding;
+ RGBA rgba;
+
+ if (Header.MajorVersion >= 4)
+ {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&PalCount, sizeof(PalCount));
+
+ Padding = (ChunkSize - 4 - 4);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+ else
+ frs.readK(&PalCount, sizeof(PalCount));
+
+ pal = new RGBA [PalCount];
+
+ if(!pal)
+ return false;
+
+ RGBA *ppal = pal;
+
+ for(u32 i = 0;i < PalCount;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA)))
+ return false;
+
+ ppal->r = rgba.b;
+ ppal->g = rgba.g;
+ ppal->b = rgba.r;
+ ppal->a = rgba.a;
+
+ ppal++;
+ }
+
+ return true;
+}
+
+/******************** ksquirrel-libs stuff ****************************/
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ Channels = 0;
+ Alpha = 0;
+ pal = 0;
+
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+ finfo.animated = false;
+
+ if(!iGetPspHead())
+ return SQE_R_BADFILE;
+
+ if(!iCheckPsp())
+ return SQE_R_BADFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ if(!ReadGenAttributes())
+ return SQE_R_BADFILE;
+
+ if(!ParseChunks())
+ return SQE_R_BADFILE;
+
+// if(!AssembleImage())
+// return SQE_R_BADFILE;
+
+ fmt_image image;
+
+ image.w = AttChunk.Width;
+ image.h = AttChunk.Height;
+ image.compression = (AttChunk.Compression == PSP_COMP_RLE ? "RLE" : "-");
+ image.bpp = (NumChannels == 1 ? 8 : ((Alpha || NumChannels == 4) ? 32 : 24));
+ image.colorspace = fmt_utils::colorSpaceByBpp(image.bpp);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+
+ fmt_image *im = image(currentImage);
+
+ u32 i, j;
+ u32 ifrom = line * im->w;
+ u32 ito = ifrom + im->w;
+
+ if (NumChannels == 1)
+ {
+ memset(scan, 0, im->w * sizeof(RGBA));
+
+ for (i = ifrom, j = 0; i < ito; i++, j++)
+ {
+ scan[j] = pal[Channels[0][i]];
+ scan[j].a = 255;
+ }
+ }
+ else
+ {
+ if (Alpha)
+ {
+ memset(scan, 0, im->w * sizeof(RGBA));
+ u8 *data = (u8 *)scan;
+
+ for (i = ifrom, j = 0; i < ito; i++, j += 4)
+ {
+ data[j ] = Channels[0][i];
+ data[j+1] = Channels[1][i];
+ data[j+2] = Channels[2][i];
+ data[j+3] = Alpha[i];
+ }
+ }
+ // 3 channels, or 4 without alpha
+ else if (NumChannels == 3 || NumChannels == 4)
+ {
+ memset(scan, 0, im->w * sizeof(RGBA));
+ u8 *data = (u8 *)scan;
+
+ for (i = ifrom, j = 0; i < ito; i++, j += 4)
+ {
+ data[j ] = Channels[0][i];
+ data[j+1] = Channels[1][i];
+ data[j+2] = Channels[2][i];
+ data[j+3] = 255;
+ }
+ }
+ else
+ return SQE_R_BADFILE;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ if(Channels)
+ {
+ for (u32 i = 0; i < NumChannels; i++)
+ delete Channels[i];
+
+ delete Channels;
+ }
+
+ delete Alpha;
+ delete pal;
+
+ Channels = 0;
+ Alpha = 0;
+ pal = 0;
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_psp/fmt_codec_psp_defs.h b/kernel/kls_psp/fmt_codec_psp_defs.h
new file mode 100644
index 0000000..a03410e
--- /dev/null
+++ b/kernel/kls_psp/fmt_codec_psp_defs.h
@@ -0,0 +1,249 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_psp
+#define KSQUIRREL_CODEC_DEFS_psp
+
+static const u8 PSPSignature[32] =
+{
+ 0x50, 0x61, 0x69, 0x6E, 0x74, 0x20, 0x53, 0x68, 0x6F, 0x70, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x49,
+ 0x6D, 0x61, 0x67, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x0A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 GenAttHead[4] = { 0x7E, 0x42, 0x4B, 0x00 };
+
+typedef u8 ILubyte;
+typedef u16 ILushort;
+typedef u32 ILuint;
+typedef s32 ILint;
+typedef double ILdouble;
+
+//-----------------------------------------------------------------------------
+//
+// ImageLib Sources
+// Copyright (C) 2000-2002 by Denton Woods
+// Last modified: 05/02/2002 <--Y2K Compliant! =]
+//
+// Filename: src-IL/include/il_psp.h
+//
+// Description: Reads a Paint Shop Pro file.
+//
+//-----------------------------------------------------------------------------
+
+
+// Block identifiers
+enum PSPBlockID {
+ PSP_IMAGE_BLOCK = 0, // (0) General Image Attributes Block (main)
+ PSP_CREATOR_BLOCK, // (1) Creator Data Block (main)
+ PSP_COLOR_BLOCK, // (2) Color Palette Block (main and sub)
+ PSP_LAYER_START_BLOCK, // (3) Layer Bank Block (main)
+ PSP_LAYER_BLOCK, // (4) Layer Block (sub)
+ PSP_CHANNEL_BLOCK, // (5) Channel Block (sub)
+ PSP_SELECTION_BLOCK, // (6) Selection Block (main)
+ PSP_ALPHA_BANK_BLOCK, // (7) Alpha Bank Block (main)
+ PSP_ALPHA_CHANNEL_BLOCK, // (8) Alpha Channel Block (sub)
+ PSP_COMPOSITE_IMAGE_BLOCK, // (9) Composite Image Block (sub)
+ PSP_EXTENDED_DATA_BLOCK, // (10) Extended Data Block (main)
+ PSP_TUBE_BLOCK, // (11) Picture Tube Data Block (main)
+ PSP_ADJUSTMENT_EXTENSION_BLOCK, // (12) Adjustment Layer Block (sub)
+ PSP_VECTOR_EXTENSION_BLOCK, // (13) Vector Layer Block (sub)
+ PSP_SHAPE_BLOCK, // (14) Vector Shape Block (sub)
+ PSP_PAINTSTYLE_BLOCK, // (15) Paint Style Block (sub)
+ PSP_COMPOSITE_IMAGE_BANK_BLOCK, // (16) Composite Image Bank (main)
+ PSP_COMPOSITE_ATTRIBUTES_BLOCK, // (17) Composite Image Attr. (sub)
+ PSP_JPEG_BLOCK, // (18) JPEG Image Block (sub)
+ PSP_LINESTYLE_BLOCK, // (19) Line Style Block (sub)
+ PSP_TABLE_BANK_BLOCK, // (20) Table Bank Block (main)
+ PSP_TABLE_BLOCK, // (21) Table Block (sub)
+ PSP_PAPER_BLOCK, // (22) Vector Table Paper Block (sub)
+ PSP_PATTERN_BLOCK, // (23) Vector Table Pattern Block (sub)
+};
+
+
+// Bitmap type
+enum PSPDIBType {
+ PSP_DIB_IMAGE = 0, // Layer color bitmap
+ PSP_DIB_TRANS_MASK, // Layer transparency mask bitmap
+ PSP_DIB_USER_MASK, // Layer user mask bitmap
+ PSP_DIB_SELECTION, // Selection mask bitmap
+ PSP_DIB_ALPHA_MASK, // Alpha channel mask bitmap
+ PSP_DIB_THUMBNAIL // Thumbnail bitmap
+};
+
+// Channel types
+enum PSPChannelType {
+ PSP_CHANNEL_COMPOSITE = 0, // Channel of single channel bitmap
+ PSP_CHANNEL_RED, // Red channel of 24 bit bitmap
+ PSP_CHANNEL_GREEN, // Green channel of 24 bit bitmap
+ PSP_CHANNEL_BLUE // Blue channel of 24 bit bitmap
+};
+
+// Possible metrics used to measure resolution
+enum PSP_METRIC {
+ PSP_METRIC_UNDEFINED = 0, // Metric unknown
+ PSP_METRIC_INCH, // Resolution is in inches
+ PSP_METRIC_CM // Resolution is in centimeters
+};
+
+
+// Possible types of compression.
+enum PSPCompression {
+ PSP_COMP_NONE = 0, // No compression
+ PSP_COMP_RLE, // RLE compression
+ PSP_COMP_LZ77, // LZ77 compression
+ PSP_COMP_JPEG // JPEG compression (only used by thumbnail and composite image)
+};
+
+// Picture tube placement mode.
+enum TubePlacementMode {
+ tpmRandom, // Place tube images in random intervals
+ tpmConstant // Place tube images in constant intervals
+};
+
+// Picture tube selection mode.
+enum TubeSelectionMode {
+ tsmRandom, // Randomly select the next image in tube to display
+ tsmIncremental, // Select each tube image in turn
+ tsmAngular, // Select image based on cursor direction
+ tsmPressure, // Select image based on pressure (from pressure-sensitive pad)
+ tsmVelocity // Select image based on cursor speed
+};
+
+// Extended data field types.
+enum PSPExtendedDataID {
+ PSP_XDATA_TRNS_INDEX = 0 // Transparency index field
+};
+
+// Creator field types.
+enum PSPCreatorFieldID {
+ PSP_CRTR_FLD_TITLE = 0, // Image document title field
+ PSP_CRTR_FLD_CRT_DATE, // Creation date field
+ PSP_CRTR_FLD_MOD_DATE, // Modification date field
+ PSP_CRTR_FLD_ARTIST, // Artist name field
+ PSP_CRTR_FLD_CPYRGHT, // Copyright holder name field
+ PSP_CRTR_FLD_DESC, // Image document description field
+ PSP_CRTR_FLD_APP_ID, // Creating app id field
+ PSP_CRTR_FLD_APP_VER, // Creating app version field
+};
+
+// Creator application identifiers.
+enum PSPCreatorAppID {
+ PSP_CREATOR_APP_UNKNOWN = 0, // Creator application unknown
+ PSP_CREATOR_APP_PAINT_SHOP_PRO // Creator is Paint Shop Pro
+};
+
+// Layer types.
+enum PSPLayerType {
+ PSP_LAYER_NORMAL = 0, // Normal layer
+ PSP_LAYER_FLOATING_SELECTION // Floating selection layer
+};
+
+struct PSPRECT
+{
+ ILuint x1,y1,x2,y2;
+} PACKED;
+
+struct PSPHEAD
+{
+ char FileSig[32];
+ ILushort MajorVersion;
+ ILushort MinorVersion;
+} PACKED;
+
+struct BLOCKHEAD
+{
+ ILubyte HeadID[4];
+ ILushort BlockID;
+ ILuint BlockLen;
+} PACKED;
+
+struct GENATT_CHUNK
+{
+ ILint Width;
+ ILint Height;
+ ILdouble Resolution;
+ ILubyte ResMetric;
+ ILushort Compression;
+ ILushort BitDepth;
+ ILushort PlaneCount;
+ ILuint ColourCount;
+ ILubyte GreyscaleFlag;
+ ILuint SizeOfImage;
+ ILint ActiveLayer;
+ ILushort LayerCount;
+ ILuint GraphicContents;
+} PACKED;
+
+struct LAYERINFO_CHUNK
+{
+ ILubyte LayerType;
+ PSPRECT ImageRect;
+ PSPRECT SavedImageRect;
+ ILubyte Opacity;
+ ILubyte BlendingMode;
+ ILubyte LayerFlags;
+ ILubyte TransProtFlag;
+ ILubyte LinkID;
+ PSPRECT MaskRect;
+ PSPRECT SavedMaskRect;
+ ILubyte MaskLinked;
+ ILubyte MaskDisabled;
+ ILubyte InvertMaskBlend;
+ ILushort BlendRange;
+ ILubyte SourceBlend1[4];
+ ILubyte DestBlend1[4];
+ ILubyte SourceBlend2[4];
+ ILubyte DestBlend2[4];
+ ILubyte SourceBlend3[4];
+ ILubyte DestBlend3[4];
+ ILubyte SourceBlend4[4];
+ ILubyte DestBlend4[4];
+ ILubyte SourceBlend5[4];
+ ILubyte DestBlend5[4];
+} PACKED;
+
+struct LAYERBITMAP_CHUNK
+{
+ ILushort NumBitmaps;
+ ILushort NumChannels;
+} PACKED;
+
+struct CHANNEL_CHUNK
+{
+ ILuint CompLen;
+ ILuint Length;
+ ILushort BitmapType;
+ ILushort ChanType;
+} PACKED;
+
+struct ALPHAINFO_CHUNK
+{
+ PSPRECT AlphaRect;
+ PSPRECT AlphaSavedRect;
+} PACKED;
+
+struct ALPHA_CHUNK
+{
+ ILushort BitmapCount;
+ ILushort ChannelCount;
+} PACKED;
+
+#endif
diff --git a/kernel/kls_pxr/Makefile.am b/kernel/kls_pxr/Makefile.am
new file mode 100644
index 0000000..9f3d4d0
--- /dev/null
+++ b/kernel/kls_pxr/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_pxr.la
+
+libkls_pxr_la_SOURCES = fmt_codec_pxr.cpp fmt_codec_pxr_defs.h
+
+libkls_pxr_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_pxr_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_pxr/fmt_codec_pxr.cpp b/kernel/kls_pxr/fmt_codec_pxr.cpp
new file mode 100644
index 0000000..5fb1b9f
--- /dev/null
+++ b/kernel/kls_pxr/fmt_codec_pxr.cpp
@@ -0,0 +1,173 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+
+#include "fmt_codec_pxr_defs.h"
+#include "fmt_codec_pxr.h"
+
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "../xpm/codec_pxr.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "Pxrar format";
+ o->filter = "*.pxr ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pxr";
+ o->pixmap = codec_pxr;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ u16 w, h;
+ u8 bppi;
+
+ frs.seekg(416, ios::beg);
+ if(!frs.readK(&h, sizeof(u16))) return SQE_R_BADFILE;
+ if(!frs.readK(&w, sizeof(u16))) return SQE_R_BADFILE;
+
+ frs.seekg(424, ios::beg);
+ if(!frs.readK(&bppi, sizeof(u8))) return SQE_R_BADFILE;
+
+ fmt_image image;
+
+ image.w = w;
+ image.h = h;
+
+ if(bppi == 0x08)
+ image.bpp = 1;
+ else if(bppi == 0x0E)
+ image.bpp = 24;
+ else if(bppi == 0x0F)
+ image.bpp = 32;
+ else
+ return SQE_R_BADFILE;
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(image.bpp);
+
+ frs.seekg(1024, ios::beg);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(im->bpp)
+ {
+ case 1:
+ {
+ u8 c;
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return SQE_R_BADFILE;
+
+ memset(scan+i, c, sizeof(RGB));
+ }
+ }
+ break;
+
+ case 24:
+ {
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ }
+ break;
+
+ case 32:
+ {
+ if(!frs.readK(scan, im->w * sizeof(RGBA)))
+ return SQE_R_BADFILE;
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_pxr/fmt_codec_pxr_defs.h b/kernel/kls_pxr/fmt_codec_pxr_defs.h
new file mode 100644
index 0000000..047828b
--- /dev/null
+++ b/kernel/kls_pxr/fmt_codec_pxr_defs.h
@@ -0,0 +1,25 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_pxr
+#define KSQUIRREL_CODEC_DEFS_pxr
+
+#endif
diff --git a/kernel/kls_ras/Makefile.am b/kernel/kls_ras/Makefile.am
new file mode 100644
index 0000000..3bae1c6
--- /dev/null
+++ b/kernel/kls_ras/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_ras.la
+
+libkls_ras_la_SOURCES = fmt_codec_ras.cpp fmt_codec_ras_defs.h
+
+libkls_ras_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_ras_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_ras/fmt_codec_ras.cpp b/kernel/kls_ras/fmt_codec_ras.cpp
new file mode 100644
index 0000000..c932d9b
--- /dev/null
+++ b/kernel/kls_ras/fmt_codec_ras.cpp
@@ -0,0 +1,361 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_ras_defs.h"
+#include "fmt_codec_ras.h"
+
+#include "../xpm/codec_ras.xpm"
+
+/*
+ *
+ * The Sun Raster image file format is the native bitmap format of the Sun
+ * Microsystems UNIX platforms using the SunOS operating system. This format is
+ * capable of storing black-and-white, gray-scale, and color bitmapped data of any
+ * pixel depth. The use of color maps and a simple Run-Length data compression
+ * are also supported. Typically, most images found on a SunOS system are Sun
+ * Raster images, and this format is supported by most UNIX imaging applications.
+ *
+ */
+
+bool fmt_readdata(ifstreamK &, u8 *, u32, bool);
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.6.3";
+ o->name = "SUN Raster";
+ o->filter = "*.ras ";
+ o->config = "";
+ o->mime = "\x0059\x00A6\x006A\x0095";
+ o->mimetype = "image/x-ras";
+ o->pixmap = codec_ras;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ rle = false;
+ isRGB = false;
+ buf = NULL;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.be_getlong(&rfh.ras_magic)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_width)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_height)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_depth)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_length)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_type)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_maptype)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&rfh.ras_maplength)) return SQE_R_BADFILE;
+
+ if(rfh.ras_magic != RAS_MAGIC) return SQE_R_BADFILE;
+
+ if(rfh.ras_type != RAS_OLD && rfh.ras_type != RAS_STANDARD && rfh.ras_type != RAS_BYTE_ENCODED && rfh.ras_type != RAS_RGB &&
+ rfh.ras_type != RAS_TIFF && rfh.ras_type != RAS_IFF && rfh.ras_type != RAS_EXPERIMENTAL)
+ return SQE_R_BADFILE;
+ else if(rfh.ras_type == RAS_EXPERIMENTAL)
+ return SQE_R_NOTSUPPORTED;
+
+ image.w = rfh.ras_width;
+ image.h = rfh.ras_height;
+ image.bpp = rfh.ras_depth;
+
+ switch(rfh.ras_maptype)
+ {
+ case RMT_NONE :
+ {
+ if (rfh.ras_depth < 24)
+ {
+ s32 numcolors = 1 << rfh.ras_depth, i;
+
+ for (i = 0; i < numcolors; i++)
+ {
+ pal[i].r = (255 * i) / (numcolors - 1);
+ pal[i].g = (255 * i) / (numcolors - 1);
+ pal[i].b = (255 * i) / (numcolors - 1);
+ }
+ }
+
+ break;
+ }
+
+ case RMT_EQUAL_RGB:
+ {
+ s8 *g, *b;
+
+ s32 numcolors = 1 << rfh.ras_depth;
+
+ s8 r[3 * numcolors];
+
+ g = r + numcolors;
+ b = g + numcolors;
+
+ if(!frs.readK(r, 3 * numcolors)) return SQE_R_BADFILE;
+
+ for(s32 i = 0; i < numcolors; i++)
+ {
+ pal[i].r = r[i];
+ pal[i].g = g[i];
+ pal[i].b = b[i];
+ }
+ break;
+ }
+
+ case RMT_RAW:
+ {
+ s8 colormap[rfh.ras_maplength];
+
+ if(!frs.readK(colormap, rfh.ras_maplength)) return SQE_R_BADFILE;
+ break;
+ }
+ }
+
+ switch(rfh.ras_type)
+ {
+ case RAS_OLD:
+ case RAS_STANDARD:
+ case RAS_TIFF:
+ case RAS_IFF:
+ break;
+
+ case RAS_BYTE_ENCODED:
+ rle = true;
+ break;
+
+ case RAS_RGB:
+ isRGB = true;
+ break;
+ }
+
+ if(rfh.ras_depth == 1)
+ linelength = (short)((rfh.ras_width / 8) + (rfh.ras_width % 8 ? 1 : 0));
+ else
+ linelength = (short)rfh.ras_width;
+
+ fill = (linelength % 2) ? 1 : 0;
+
+ buf = new u8 [rfh.ras_width * sizeof(RGB)];
+
+ if(!buf)
+ return SQE_R_NOMEMORY;
+
+ image.compression = ((isRGB) ? "-":"RLE");
+ image.colorspace = "RGB";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ u32 i;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(im->bpp)
+ {
+ case 1:
+ break;
+
+ case 8:
+ if(!fmt_readdata(frs, buf, linelength, rle))
+ return SQE_R_BADFILE;
+
+ for(i = 0;i < rfh.ras_width;i++)
+ memcpy(scan+i, &pal[i], sizeof(RGB));
+
+ if(fill)
+ {
+ if(!fmt_readdata(frs, &fillchar, fill, rle))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 24:
+ {
+ u8 *b = buf;
+
+ if(!fmt_readdata(frs, buf, rfh.ras_width * 3, rle))
+ return SQE_R_BADFILE;
+
+ if(isRGB)
+ for (i = 0; i < rfh.ras_width; i++)
+ {
+ scan[i].r = *b;
+ scan[i].g = *(b+1);
+ scan[i].b = *(b+2);
+ b += 3;
+ }
+ else
+ for (i = 0; i < rfh.ras_width; i++)
+ {
+ scan[i].r = *(b + 2);
+ scan[i].g = *(b + 1);
+ scan[i].b = *b;
+ b += 3;
+ }
+
+ if(fill)
+ {
+ if(!fmt_readdata(frs, &fillchar, fill, rle))
+ return SQE_R_BADFILE;
+ }
+ }
+ break;
+
+ case 32:
+ {
+ u8 *b = buf;
+
+ if(!fmt_readdata(frs, buf, rfh.ras_width * 4, rle))
+ return SQE_R_BADFILE;
+
+ if(isRGB)
+ for (i = 0; i < rfh.ras_width; i++)
+ {
+ scan[i].a = *b;
+ scan[i].r = *(b+1);
+ scan[i].g = *(b+2);
+ scan[i].b = *(b+3);
+ b += 4;
+ }
+ else
+ for (i = 0; i < rfh.ras_width; i++)
+ {
+ scan[i].r = *(b + 3);
+ scan[i].g = *(b + 2);
+ scan[i].b = *(b + 1);
+ scan[i].a = *b;
+ b += 4;
+ }
+
+ if(fill)
+ {
+ if(!fmt_readdata(frs, &fillchar, fill, rle))
+ return SQE_R_BADFILE;
+ }
+
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ delete [] buf;
+ buf = NULL;
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool fmt_readdata(ifstreamK &ff, u8 *_buf, u32 length, bool rle)
+{
+ u8 repchar, remaining = 0;
+
+ if(rle)
+ {
+ while(length--)
+ {
+ if (remaining)
+ {
+ remaining--;
+ *(_buf++)= repchar;
+ }
+ else
+ {
+ if(!ff.readK(&repchar, 1)) return false;
+
+ if(repchar == RESC)
+ {
+ if(!ff.readK(&remaining, 1)) return false;
+
+ if (remaining == 0)
+ *(_buf++) = RESC;
+ else
+ {
+ if(!ff.readK(&repchar, 1)) return false;
+ *(_buf++) = repchar;
+ }
+ }
+ else
+ *(_buf++) = repchar;
+ }
+ }
+ }
+ else
+ {
+ if(!ff.readK(_buf, length)) return false;
+
+ }
+
+ return true;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_ras/fmt_codec_ras_defs.h b/kernel/kls_ras/fmt_codec_ras_defs.h
new file mode 100644
index 0000000..aca1829
--- /dev/null
+++ b/kernel/kls_ras/fmt_codec_ras_defs.h
@@ -0,0 +1,54 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_ras
+#define KSQUIRREL_READ_IMAGE_ras
+
+struct RAS_HEADER
+{
+ u32 ras_magic;
+ u32 ras_width;
+ u32 ras_height;
+ u32 ras_depth;
+ u32 ras_length;
+ u32 ras_type;
+ u32 ras_maptype;
+ u32 ras_maplength;
+
+}PACKED;
+
+#define RAS_MAGIC 0x59A66A95 // Magic number for Sun rasterfiles
+
+#define RAS_OLD 0 // Old format (raw image in 68000 byte order)
+#define RAS_STANDARD 1 // Raw image in 68000 byte order
+#define RAS_BYTE_ENCODED 2 // Run-length encoding of bytes
+#define RAS_RGB 3 // XRGB or RGB instead of XBGR or BGR
+#define RAS_TIFF 4 // TIFF <-> standard rasterfile
+#define RAS_IFF 5 // IFF (TAAC format) <-> standard rasterfile
+
+#define RAS_EXPERIMENTAL 0xffff // Reserved for testing
+
+#define RMT_NONE 0 // maplength is expected to be 0
+#define RMT_EQUAL_RGB 1 // red[maplength/3], green[maplength/3], blue[maplength/3]
+#define RMT_RAW 2 // Raw colormap
+#define RESC 128 // Run-length encoding escape character
+
+#endif
diff --git a/kernel/kls_rawrgb/Makefile.am b/kernel/kls_rawrgb/Makefile.am
new file mode 100644
index 0000000..a12c81e
--- /dev/null
+++ b/kernel/kls_rawrgb/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_rawrgb.la
+
+libkls_rawrgb_la_SOURCES = fmt_codec_rawrgb.cpp fmt_codec_rawrgb_defs.h
+
+libkls_rawrgb_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_rawrgb_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_rawrgb/fmt_codec_rawrgb.cpp b/kernel/kls_rawrgb/fmt_codec_rawrgb.cpp
new file mode 100644
index 0000000..2379974
--- /dev/null
+++ b/kernel/kls_rawrgb/fmt_codec_rawrgb.cpp
@@ -0,0 +1,229 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_rawrgb_defs.h"
+#include "fmt_codec_rawrgb.h"
+
+#include "../xpm/codec_rawrgb.xpm"
+
+/*
+ *
+ * This is a codec to read and write internal raw image format.
+ * This format has a simple header folowed by uncompressed image data in
+ * 24 or 32 bit format. Width, height and bit depth are integers (unsigned int, or u32).
+ *
+ * File structure:
+ *
+ * <WIDTH><HEIGHT><BIT_DEPTH>
+ * <UNCOMPRESSED IMAGE DATA>
+ *
+ * Example:
+ *
+ * [ 32][ 32][ 24]
+ * [RGB][RGB][RGB][RGB]...
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "1.0.0";
+ o->name = "Raw uncompressed RGB image";
+ o->filter = "*.rawrgb ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-rawrgb";
+ o->pixmap = codec_rawrgb;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ u32 w, h, bpp;
+ frs.readK(&w, sizeof(u32));
+ frs.readK(&h, sizeof(u32));
+ frs.readK(&bpp, sizeof(u32));
+
+ if(bpp != 32 && bpp != 24)
+ return SQE_R_BADFILE;
+
+ image.w = w;
+ image.h = h;
+ image.bpp = bpp;
+ image.compression = "-";
+ image.colorspace = (bpp == 24 ? "RGB" : "RGBA");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ RGBA rgba;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ if(im->bpp == 32)
+ for(s32 i = 0;i < im->w;i++)
+ {
+ frs.readK(&rgba, sizeof(RGBA));
+ memcpy(scan+i, &rgba, sizeof(RGBA));
+ }
+ else
+ for(s32 i = 0;i < im->w;i++)
+ {
+ frs.readK(&rgb, sizeof(RGB));
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ s32 bpp = 32;
+
+ if(!fws.writeK(&writeimage.w, sizeof(s32))) return SQE_W_ERROR;
+ if(!fws.writeK(&writeimage.h, sizeof(s32))) return SQE_W_ERROR;
+ if(!fws.writeK(&bpp, sizeof(s32))) return SQE_W_ERROR;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ u8 *p, a;
+
+ for(s32 j = 0;j < writeimage.w;j++)
+ {
+ p = (u8 *)(scan +j);
+
+ fws.writeK(p, sizeof(u8));
+ fws.writeK(p+1, sizeof(u8));
+ fws.writeK(p+2, sizeof(u8));
+
+ a = (writeopt.alpha) ? *(p+3) : 255;
+
+ if(!fws.writeK(&a, sizeof(u8))) return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("rawrgb");
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_rawrgb/fmt_codec_rawrgb_defs.h b/kernel/kls_rawrgb/fmt_codec_rawrgb_defs.h
new file mode 100644
index 0000000..afe6292
--- /dev/null
+++ b/kernel/kls_rawrgb/fmt_codec_rawrgb_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_rawrgb
+#define KSQUIRREL_READ_IMAGE_rawrgb
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_sct/Makefile.am b/kernel/kls_sct/Makefile.am
new file mode 100644
index 0000000..826c167
--- /dev/null
+++ b/kernel/kls_sct/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_sct.la
+
+libkls_sct_la_SOURCES = fmt_codec_sct.cpp fmt_codec_sct_defs.h
+
+libkls_sct_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_sct_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_sct/fmt_codec_sct.cpp b/kernel/kls_sct/fmt_codec_sct.cpp
new file mode 100644
index 0000000..90048e4
--- /dev/null
+++ b/kernel/kls_sct/fmt_codec_sct.cpp
@@ -0,0 +1,232 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_sct_defs.h"
+#include "fmt_codec_sct.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_sct.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.2.2";
+ o->name = "Scitex CT";
+ o->filter = "*.sct *.ct ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-sct";
+ o->pixmap = codec_sct;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 comment[0x50 + 1], sig[2];
+
+ if(!frs.readK(comment, sizeof(comment) - 1)) return SQE_R_BADFILE;
+ if(!frs.readK(sig, sizeof(sig))) return SQE_R_BADFILE;
+
+ comment[0x50] = '\0';
+
+ frs.seekg(0x400, ios::beg);
+
+ if(!frs.readK(&sct, sizeof(sct_header))) return SQE_R_BADFILE;
+
+ sct.format = fmt_utils::konvertWord(sct.format);
+
+ if(sct.format != SCT_FORMAT_RGB && sct.format != SCT_FORMAT_GRAY && sct.format != SCT_FORMAT_CMYK)
+ return SQE_R_BADFILE;
+
+ if(sct.format == SCT_FORMAT_RGB && sct.channels != 3)
+ return SQE_R_BADFILE;
+
+ if(sct.format == SCT_FORMAT_GRAY && sct.channels != 1)
+ return SQE_R_BADFILE;
+
+ if(sct.format == SCT_FORMAT_CMYK && sct.channels != 4)
+ return SQE_R_BADFILE;
+
+ if((sct.width[0] != '+' && sct.width[0] != '-') || (sct.height[0] != '+' && sct.height[0] != '-'))
+ return SQE_R_BADFILE;
+
+ std::string buf;
+
+ buf.assign(sct.width, sizeof(sct.width));
+
+ std::stringstream ss(buf);
+
+ ss.setf(ios::hex);
+
+ ss >> image.h;
+
+ buf.assign(sct.height, sizeof(sct.height));
+
+ std::stringstream ss1(buf);
+
+ ss1.setf(ios::hex);
+
+ ss1 >> image.w;
+
+ image.compression = "-";
+
+ switch(sct.format)
+ {
+ case SCT_FORMAT_RGB:
+ image.colorspace = "RGB";
+ image.bpp = 24;
+ break;
+
+ case SCT_FORMAT_GRAY:
+ image.colorspace = "Grayscale";
+ image.bpp = 8;
+ break;
+
+ case SCT_FORMAT_CMYK:
+ image.colorspace = "CMYK";
+ image.bpp = 32;
+ break;
+ }
+
+ fmt_metaentry mt;
+
+ mt.group = "Comment";
+ mt.data = comment;
+
+ addmeta(mt);
+
+ finfo.image.push_back(image);
+
+ frs.seekg(0x800, ios::beg);
+
+ return (frs.good()) ? SQE_OK : SQE_R_BADFILE;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ RGBA rgba;
+ u8 c, *p;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(sct.format)
+ {
+ case SCT_FORMAT_RGB:
+ for(s32 ch = 0;ch < 3;ch++)
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return SQE_R_BADFILE;
+
+ p = (u8 *)(scan + i);
+ *(p + ch) = c;
+ }
+ break;
+
+ case SCT_FORMAT_GRAY:
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&c, sizeof(c))) return SQE_R_BADFILE;
+
+ (scan+i)->r = c;
+ (scan+i)->g = c;
+ (scan+i)->b = c;
+ }
+ break;
+
+ case SCT_FORMAT_CMYK:
+ for(s32 ch = 0;ch < 4;ch++)
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&c, sizeof(u8))) return SQE_R_BADFILE;
+
+ p = (u8 *)(scan + i);
+ *(p + ch) = c;
+ }
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ scan[i].r = (scan[i].r * scan[i].a) >> 8;
+ scan[i].g = (scan[i].g * scan[i].a) >> 8;
+ scan[i].b = (scan[i].b * scan[i].a) >> 8;
+ scan[i].a = 255;
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_sct/fmt_codec_sct_defs.h b/kernel/kls_sct/fmt_codec_sct_defs.h
new file mode 100644
index 0000000..bffa9f2
--- /dev/null
+++ b/kernel/kls_sct/fmt_codec_sct_defs.h
@@ -0,0 +1,51 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_sct
+#define KSQUIRREL_CODEC_DEFS_sct
+
+#define SCT_UNITS_MM 0
+#define SCT_UNITS_INCH 1
+
+#define SCT_FORMAT_RGB 7
+#define SCT_FORMAT_GRAY 8
+#define SCT_FORMAT_CMYK 0xf
+
+//
+// SCT header starts from offset 0x400. Before it
+// comes comment string (50 symbols, offset 0x0)
+// and signature "CT" (offset 0x50).
+//
+// Image pixels are stored from file offset 0x800
+//
+
+struct sct_header
+{
+ u8 units; // units (0=MM,1=INCH)
+ u8 channels; // number of channels
+ u16 format; // format (7=RGB, 8=GREYSCALE, 0xF=CMYK)
+ s8 wh_units[28]; // width and height in units stored as a Scitex FP (not used)
+ s8 width[12]; // width in pixels stored as 12 digits of text including sign ("%+012d").
+ s8 height[12]; // height in pixels stored as 12 digits of text including sign ("%+012d").
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_sgi/Makefile.am b/kernel/kls_sgi/Makefile.am
new file mode 100644
index 0000000..6284c4c
--- /dev/null
+++ b/kernel/kls_sgi/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_sgi.la
+
+libkls_sgi_la_SOURCES = fmt_codec_sgi.cpp fmt_codec_sgi_defs.h
+
+libkls_sgi_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_sgi_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_sgi/fmt_codec_sgi.cpp b/kernel/kls_sgi/fmt_codec_sgi.cpp
new file mode 100644
index 0000000..0ec1ea4
--- /dev/null
+++ b/kernel/kls_sgi/fmt_codec_sgi.cpp
@@ -0,0 +1,341 @@
+/* This file is part of SQuirrel (http://ksquirrel.sf.net) libraries
+
+ Copyright (c) 2004 Dmitry Baryshev <ckult@yandex.ru>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_sgi_defs.h"
+#include "fmt_codec_sgi.h"
+
+#include "../xpm/codec_sgi.xpm"
+
+/*
+ *
+ * The SGI image file format is actually part of the SGI image library found on
+ * all Silicon Graphics machines. SGI image files may store black-and-white (.BW
+ * extension), color RGB (.RGB extension),
+ * or color RGB with alpha channel data (.RGBA extension)
+ * images. SGI image files may also have the generic extension .SGI as well.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.9.4";
+ o->name = "SGI Format";
+ o->filter = "*.rgb *.rgba *.bw";
+ o->config = "";
+ o->mime = "\001\332.[\001\002]";
+ o->mimetype = "image/x-rgb";
+ o->pixmap = codec_sgi;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ starttab = NULL;
+ lengthtab = NULL;
+ channel[0] = channel[1] = channel[2] = channel[3] = NULL;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.be_getshort(&sfh.Magik)) return SQE_R_BADFILE;
+ if(!frs.readK(&sfh.StorageFormat, 1)) return SQE_R_BADFILE;
+ if(!frs.readK(&sfh.bpc, 1)) return SQE_R_BADFILE;
+ if(!frs.be_getshort(&sfh.Dimensions)) return SQE_R_BADFILE;
+ if(!frs.be_getshort(&sfh.x)) return SQE_R_BADFILE;
+ if(!frs.be_getshort(&sfh.y)) return SQE_R_BADFILE;
+ if(!frs.be_getshort(&sfh.z)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&sfh.pixmin)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&sfh.pixmax)) return SQE_R_BADFILE;
+ if(!frs.be_getlong(&sfh.dummy)) return SQE_R_BADFILE;
+
+ if(!frs.readK(sfh.name, sizeof(sfh.name))) return SQE_R_BADFILE;
+
+ if(!frs.be_getlong(&sfh.ColormapID)) return SQE_R_BADFILE;
+
+ if(!frs.readK(&sfh.dummy2, sizeof(sfh.dummy2))) return SQE_R_BADFILE;
+
+ image.w = sfh.x;
+ image.h = sfh.y;
+ image.bpp = sfh.bpc * sfh.z * 8;
+
+ if(image.bpp == 32) image.hasalpha = true;
+
+ if(sfh.Magik != 474 || (sfh.StorageFormat != 0 && sfh.StorageFormat != 1) || (sfh.Dimensions != 1 && sfh.Dimensions != 2 && sfh.Dimensions != 3) || (sfh.bpc != 1 && sfh.bpc != 2))
+ return SQE_R_BADFILE;
+
+ if(sfh.bpc == 2 || sfh.ColormapID > 0)
+ return SQE_R_NOTSUPPORTED;
+
+ for(s32 i = 0;i < 4;i++)
+ {
+ channel[i] = new s8 [sfh.x];
+
+ if(!channel[i])
+ return SQE_R_NOMEMORY;
+ }
+
+ if(sfh.StorageFormat == 1)
+ {
+ s32 sz = sfh.y * sfh.z, i;
+ lengthtab = new u32 [sz];
+ starttab = new u32 [sz];
+
+ if(!lengthtab || !starttab)
+ return SQE_R_NOMEMORY;
+
+ frs.seekg(512, ios::beg);
+
+ for(i = 0;i < sz;i++)
+ if(!frs.be_getlong(&starttab[i]))
+ return SQE_R_BADFILE;
+
+ for(i = 0;i < sz;i++)
+ if(!frs.be_getlong(&lengthtab[i]))
+ return SQE_R_BADFILE;
+ }
+
+ rle_row = 0;
+
+ if(strlen(sfh.name))
+ {
+ fmt_metaentry mt;
+
+ mt.group = "Image Name";
+ mt.data = sfh.name;
+
+ addmeta(mt);
+ }
+
+ image.needflip = true;
+ image.compression = (sfh.StorageFormat ? "RLE" : "-");
+ image.colorspace = fmt_utils::colorSpaceByBpp(image.bpp);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ const s32 sz = sfh.x;
+ s32 i = 0, j = 0;
+ s32 len;
+ fstream::pos_type pos;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ s8 bt;
+
+ memset(channel[3], 255, sz);
+
+ switch(sfh.z)
+ {
+ case 1:
+ {
+ if(sfh.StorageFormat)
+ {
+ j = 0;
+
+ frs.seekg(starttab[rle_row], ios::beg);
+ len = lengthtab[rle_row];
+
+ for(;;)
+ {
+ s8 count;
+
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+ count = bt&0x7f;
+
+ if(!count) break;
+
+ if(bt & 0x80)
+ while(count--)
+ {
+ if(!frs.readK(&channel[0][j], 1)) return SQE_R_BADFILE;
+
+ j++;
+
+ if(!len--) goto ex1;
+ }
+ else
+ {
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ if(!len--) goto ex1;
+
+ while(count--)
+ channel[0][j++] = bt;
+ }
+ }
+ ex1:
+ len = len; // some stuff: get rid of compile warning
+
+ rle_row++;
+ }
+ else
+ {
+ if(!frs.readK(channel[0], sz)) return SQE_R_BADFILE;
+ }
+
+ memcpy(channel[1], channel[0], sz);
+ memcpy(channel[2], channel[0], sz);
+ }
+ break;
+
+
+ case 3:
+ case 4:
+ {
+ if(sfh.StorageFormat)
+ {
+ for(i = 0;i < sfh.z;i++)
+ {
+ j = 0;
+
+ frs.seekg(starttab[rle_row + i*im->h], ios::beg);
+ len = lengthtab[rle_row + i*im->h];
+
+ for(;;)
+ {
+ s8 count;
+
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ count = bt&0x7f;
+
+ if(!count) break;
+
+ if(bt & 0x80)
+ while(count--)
+ {
+ if(!frs.readK(&channel[i][j], 1)) return SQE_R_BADFILE;
+ j++;
+ if(!len--) goto ex;
+ }
+ else
+ {
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ if(!len--) goto ex;
+
+ while(count--)
+ channel[i][j++] = bt;
+ }
+ }
+ ex:
+ len = len; // some stuff: get rid of compile warning
+ }
+ rle_row++;
+ }
+ else
+ {
+ if(!frs.readK(channel[0], sz)) return SQE_R_BADFILE;
+
+ pos = frs.tellg();
+ frs.seekg(im->w * (im->h - 1), ios::cur);
+ if(!frs.readK(channel[1], sz)) return SQE_R_BADFILE;
+
+ frs.seekg(im->w * (im->h - 1), ios::cur);
+ if(!frs.readK(channel[2], sz)) return SQE_R_BADFILE;
+
+ frs.seekg(im->w * (im->h - 1), ios::cur);
+ if(!frs.readK(channel[3], sz)) return SQE_R_BADFILE;
+
+ frs.seekg(pos);
+ }
+
+ }
+ break;
+ }
+
+ for(i = 0;i < sz;i++)
+ {
+ scan[i].r = channel[0][i];
+ scan[i].g = channel[1][i];
+ scan[i].b = channel[2][i];
+ scan[i].a = channel[3][i];
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ delete [] starttab;
+ starttab = NULL;
+
+ delete [] lengthtab;
+ lengthtab = NULL;
+
+ for(s32 i = 0;i < 4;i++)
+ {
+ delete [] channel[i];
+ channel[i] = NULL;
+ }
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_sgi/fmt_codec_sgi_defs.h b/kernel/kls_sgi/fmt_codec_sgi_defs.h
new file mode 100644
index 0000000..3573d4e
--- /dev/null
+++ b/kernel/kls_sgi/fmt_codec_sgi_defs.h
@@ -0,0 +1,50 @@
+/* This file is part of SQuirrel (http://ksquirrel.sf.net) libraries
+
+ Copyright (c) 2004 Dmitry Baryshev <ckult@yandex.ru>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_sgi
+#define KSQUIRREL_READ_IMAGE_sgi
+
+struct SGI_HEADER
+{
+ u16 Magik; /* should be 474 */
+ u8 StorageFormat; /* 1 == RLE, 0 = Verbatim */
+ u8 bpc; /* 1|2 */
+ u16 Dimensions; /* 1|2|3 1==1channle+1scanline, 2==1channle+some scanlines, 3==number of channels */
+ u16 x;
+ u16 y;
+ u16 z;
+ u32 pixmin;
+ u32 pixmax;
+ u32 dummy;
+ char name[80]; /* ascii string */
+ u32 ColormapID;
+
+ /* 0=Normal
+ 1=Dither. RGB==3:3:2 per byte, 1 channel
+ 2=Screen. Obsolete
+ 3=Colormap. Has ONLY colormap, nothing else.
+ */
+
+ u8 dummy2[404];
+
+}PACKED;
+
+#endif
diff --git a/kernel/kls_sun/Makefile.am b/kernel/kls_sun/Makefile.am
new file mode 100644
index 0000000..b7b3b16
--- /dev/null
+++ b/kernel/kls_sun/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_sun.la
+
+libkls_sun_la_SOURCES = fmt_codec_sun.cpp fmt_codec_sun_defs.h
+
+libkls_sun_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_sun_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_sun/fmt_codec_sun.cpp b/kernel/kls_sun/fmt_codec_sun.cpp
new file mode 100644
index 0000000..d12612d
--- /dev/null
+++ b/kernel/kls_sun/fmt_codec_sun.cpp
@@ -0,0 +1,235 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <cctype>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_sun_defs.h"
+#include "fmt_codec_sun.h"
+
+#include "../xpm/codec_sun.xpm"
+
+/*
+ *
+ * The icons found in the Open Look and SunView Graphical User Interfaces available
+ * on the Sun Microsystems UNIX-based platforms are stored in a simple format known
+ * as the Sun Icon format
+ *
+ */
+
+static const RGB mono[2] = { RGB(255,255,255), RGB(0,0,0) };
+
+static const char * lex[5] =
+{
+ "Format_version",
+ "Width",
+ "Height",
+ "Depth",
+ "Valid_bits_per_item"
+};
+
+// internal function
+bool scanForLex(ifstreamK &f, bool digit = false);
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.9.1";
+ o->name = "SUN Icon";
+ o->filter = "*.sun ";
+ o->config = "";
+ o->mime = "/\\* Format_";
+ o->mimetype = "image/x-sun";
+ o->pixmap = codec_sun;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[128];
+ u32 var, ver;
+
+ u32 * pointers[5] =
+ {
+ &ver,
+ (u32 *)&image.w,
+ (u32 *)&image.h,
+ (u32 *)&image.bpp,
+ &validbits
+ };
+
+ for(s32 i = 0;i < 5;i++)
+ {
+ if(!scanForLex(frs))
+ return SQE_R_BADFILE;
+
+ frs.getline(str, 127, '=');
+
+ if(!frs.good())
+ return SQE_R_BADFILE;
+
+ if(strncmp(lex[i], str, strlen(lex[i])))
+ return SQE_R_BADFILE;
+
+ frs >> var;
+
+ *(pointers[i]) = var;
+ }
+
+ if(ver != SUN_ICON_VERSION)
+ return SQE_R_BADFILE;
+
+ // ignore images with width != 64 or height != 64
+ // TODO: get rid of this if()
+ if(image.w != 64 || image.h != 64)
+ return SQE_R_NOTSUPPORTED;
+
+ if(image.bpp != 1)
+ return SQE_R_NOTSUPPORTED;
+
+ if(validbits != 16 && validbits != 32)
+ return SQE_R_BADFILE;
+
+ if(!scanForLex(frs, true))
+ return SQE_R_BADFILE;
+
+ image.compression = "-";
+ image.colorspace = "Monochrome";
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ RGBA rgba;
+ u32 var, i = 0, j = 0;
+ s32 decoded = 0;
+ u8 indexes[32];
+ bool lasthex;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ while(decoded < im->w)
+ {
+ if(!frs.readCHex(var))
+ return SQE_R_BADFILE;
+
+ if(validbits == 16)
+ fmt_utils::expandMono2Byte(var, indexes);
+ else
+ fmt_utils::expandMono4Byte(var, indexes);
+
+ decoded += validbits;
+
+ lasthex = (decoded >= im->w && line == im->h-1);
+
+ if(!scanForLex(frs, true) && !lasthex)
+ return SQE_R_BADFILE;
+
+ j = i + validbits;
+
+ for(u32 k = 0;i < j;i++,k++)
+ memcpy(scan+i, mono+indexes[k], sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool scanForLex(ifstreamK &f, bool digit)
+{
+ u8 c;
+ bool found = false;
+
+ while(f.readK(&c, sizeof(u8)))
+ {
+// cout << "Read " << c << endl;
+
+ if((!digit && isalpha(c)) || (digit && isdigit(c)))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if(found)
+ f.seekg(-1, ios::cur);
+
+ return found;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_sun/fmt_codec_sun_defs.h b/kernel/kls_sun/fmt_codec_sun_defs.h
new file mode 100644
index 0000000..bab52a6
--- /dev/null
+++ b/kernel/kls_sun/fmt_codec_sun_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_sun
+#define KSQUIRREL_READ_IMAGE_sun
+
+#define SUN_ICON_VERSION 1
+
+#endif
diff --git a/kernel/kls_svg/Makefile.am b/kernel/kls_svg/Makefile.am
new file mode 100644
index 0000000..2bbc93d
--- /dev/null
+++ b/kernel/kls_svg/Makefile.am
@@ -0,0 +1,19 @@
+INCLUDES = -I../include -I../kls_png
+
+bin_SCRIPTS = ksquirrel-libs-svg2png
+
+pkglib_LTLIBRARIES = libkls_svg.la
+
+libkls_svg_la_SOURCES = fmt_codec_png.cpp fmt_codec_png_defs.h
+
+libkls_svg_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_svg_la_LIBADD = ${SQ_LOCAL_RPATH} -L../kls_png/ksquirrel-libs-png -lksquirrel-libs-png
+
+AM_CXXFLAGS = -DCODEC_SVG -DCODEC_ANOTHER -DSVG_UI=\"${pkgdatadir}/libkls_svg.so.ui\" -DRSVG=\"${RSVG}\" -DSVG2PNG=\"${bindir}/ksquirrel-libs-svg2png\"
+
+EXTRA_DIST = libkls_svg.so.ui ksquirrel-libs-svg2png.in
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 libkls_svg.so.ui $(DESTDIR)$(pkgdatadir)/libkls_svg.so.ui
diff --git a/kernel/kls_svg/fmt_codec_png.cpp b/kernel/kls_svg/fmt_codec_png.cpp
new file mode 100644
index 0000000..66c43ee
--- /dev/null
+++ b/kernel/kls_svg/fmt_codec_png.cpp
@@ -0,0 +1,655 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs-png/png.h"
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_png_defs.h"
+#include "fmt_codec_png.h"
+
+#if defined CODEC_SVG || defined CODEC_DICOM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_SVG
+#include "../xpm/codec_svg.xpm"
+#elif defined CODEC_DICOM
+#include "../xpm/codec_dicom.xpm"
+#else
+#include "../xpm/codec_png.xpm"
+#endif
+
+/*
+ *
+ * PNG (pronounced "ping") is a bitmap file format used to transmit and
+ * store bitmapped images. PNG supports the capability of storing up to
+ * 16 bits (gray-scale) or 48 bits (truecolor) per pixel, and up to 16 bits
+ * of alpha data. It handles the progressive display
+ * of image data and the storage of gamma,
+ * transparency and textual information, and it uses an efficient and
+ * lossless form of data compression.
+ *
+ */
+
+inline bool MALLOC_ROWS(png_bytep **A, const int RB, const int H)
+{
+ *A = (png_bytep*)malloc(H * sizeof(png_bytep*));
+
+ if(!*A)
+ return false;
+
+ for(s32 row = 0; row < H; row++)
+ (*A)[row] = 0;
+
+ for(s32 row = 0; row < (s32)H; row++)
+ {
+ (*A)[row] = (png_bytep)malloc(RB);
+
+ if(!(*A)[row])
+ return false;
+
+ memset((*A)[row], 0, RB);
+ }
+
+ return true;
+}
+
+inline void FREE_ROWS(png_bytep **A, const int H)
+{
+ if(*A)
+ {
+ for(s32 i = 0;i < H;i++)
+ {
+ if((*A)[i])
+ free((*A)[i]);
+ }
+
+ free(*A);
+ *A = 0;
+ }
+}
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+#ifdef CODEC_SVG
+ o->version = "0.1.2";
+ o->name = "Scalable Vector Graphics";
+ o->filter = "*.svg *.svgz ";
+ o->config = std::string(SVG_UI); // SVG_UI comes from Makefile.am
+ o->mime = "";
+ o->mimetype = "image/svg+xml";
+ o->pixmap = codec_svg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DICOM
+ o->version = "1.1.3";
+ o->name = "DICOM";
+ o->filter = "*.dcm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-dicom";
+ o->pixmap = codec_dicom;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "1.1.3";
+ o->name = "Portable Network Graphics";
+ o->filter = "*.png ";
+ o->config = "";
+ o->mime = "\x0089\x0050\x004E\x0047\x000D\x000A\x001A\x000A";
+ o->mimetype = "image/png";
+ o->pixmap = codec_png;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#ifdef CODEC_ANOTHER
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_int;
+ val.iVal = 1;
+
+ m_settings["scale"] = val;
+}
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ png_ptr = 0;
+ info_ptr = 0;
+ fptr = 0;
+ frame = 0;
+ prev = 0;
+ cur = 0;
+ zerror = false;
+
+#ifdef CODEC_SVG
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("scale");
+
+ // percents / 100
+ int scale = (it == m_settings.end() || (*it).second.type != settings_value::v_int)
+ ? 1 : (*it).second.iVal;
+
+ if(scale < 1 || scale > 10)
+ scale = 1;
+
+ char z[32];
+ snprintf(z, 32, "%d", scale);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(SVG2PNG, SVG2PNG, "--binary", RSVG, "--input", file.c_str(), "--output", tmp.c_str(), "-z", z, (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DICOM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DICOM, DICOM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+ fptr = fopen(file.c_str(), "rb");
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ if((png_ptr = my_png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)) == NULL)
+ {
+ zerror = true;
+ return SQE_R_NOMEMORY;
+ }
+
+ if((info_ptr = my_png_create_info_struct(png_ptr)) == NULL)
+ {
+ zerror = true;
+ return SQE_R_NOMEMORY;
+ }
+
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ my_png_init_io(png_ptr, fptr);
+ my_png_read_info(png_ptr, info_ptr);
+ my_png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, (int*)0, (int*)0);
+
+ img.w = next_frame_width = width;
+ img.h = next_frame_height = height;
+ img.bpp = bit_depth;
+
+ if(img.bpp == 16)
+ my_png_set_strip_16(png_ptr);
+
+ if(img.bpp < 8)
+ my_png_set_packing(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_GRAY && img.bpp < 8)
+ my_png_set_gray_1_2_4_to_8(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_PALETTE)
+ my_png_set_palette_to_rgb(png_ptr);
+
+ if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ my_png_set_gray_to_rgb(png_ptr);
+
+ if(my_png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ my_png_set_tRNS_to_alpha(png_ptr);
+
+ my_png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+ number_passes = my_png_set_interlace_handling(png_ptr);
+
+ my_png_read_update_info(png_ptr, info_ptr);
+
+ finfo.animated = !!my_png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL);
+
+ frames = finfo.animated ? my_png_get_num_frames(png_ptr, info_ptr) : 1;
+
+ if(!frames) return SQE_R_BADFILE;
+
+ img.interlaced = number_passes > 1;
+ img.passes = finfo.animated ? 1 : number_passes;
+
+ if(finfo.animated)
+ {
+ if(!MALLOC_ROWS(&prev, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+
+ if(!MALLOC_ROWS(&cur, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+ }
+
+ std::string color_;
+
+ img.hasalpha = (color_type & PNG_COLOR_MASK_ALPHA);
+
+ switch((color_type & ~PNG_COLOR_MASK_ALPHA))
+ {
+ case PNG_COLOR_TYPE_RGB: color_ = "RGB"; break;
+ case PNG_COLOR_TYPE_PALETTE: color_ = "Color indexed"; break;
+ case PNG_COLOR_TYPE_GRAY: color_ = "Grayscale"; break;
+
+ default:
+ color_ = "Unknown";
+ }
+
+ if(img.hasalpha)
+ color_ += " with ALPHA";
+
+ img.compression = "Deflate method 8, 32K window";
+ img.colorspace = color_;
+ if(!finfo.animated) img.delay = 0;
+
+#ifdef PNG_TEXT_SUPPORTED
+ png_textp lines = info_ptr->text;
+
+ if(!lines || !info_ptr->num_text)
+ return SQE_OK;
+
+ for(s32 i = 0;i < info_ptr->num_text;i++)
+ {
+ fmt_metaentry mt;
+
+ mt.group = lines[i].key;
+ mt.data = lines[i].text;
+
+ addmeta(mt);
+ }
+#endif
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == frames)
+ return SQE_NOTOK;
+
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ if(finfo.animated)
+ {
+ if(currentImage)
+ {
+ if(next_frame_dispose_op == PNG_DISPOSE_OP_BACKGROUND)
+ {
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ memset(cur[j]+next_frame_x_offset*sizeof(RGBA), 0, next_frame_width * sizeof(RGBA));
+ }
+ else if(next_frame_dispose_op == PNG_DISPOSE_OP_PREVIOUS)
+ {
+ for(u32 i = 0;i < height;i++)
+ memcpy(cur[i], prev[i], width*sizeof(RGBA));
+ }
+ else // next_frame_dispose_op == PNG_DISPOSE_OP_NONE
+ {
+ }
+
+ for(u32 i = 0;i < height;i++)
+ memcpy(prev[i], cur[i], width*sizeof(RGBA));
+ }
+ else if(my_png_get_first_frame_is_hidden(png_ptr, info_ptr))
+ {
+ if(!MALLOC_ROWS(&frame, width * sizeof(RGBA), height))
+ return SQE_R_NOMEMORY;
+
+ my_png_read_frame_head(png_ptr, info_ptr);
+ my_png_read_image(png_ptr, frame);
+
+ FREE_ROWS(&frame, height);
+
+ frames--;
+
+ if(frames == 1)
+ {
+ my_png_read_frame_head(png_ptr, info_ptr);
+ finfo.animated = false;
+ img.passes = number_passes;
+ finfo.image.push_back(img);
+ return SQE_OK;
+ }
+ else if(!frames)
+ return SQE_R_BADFILE; // oops?
+ }
+
+ FREE_ROWS(&frame, next_frame_height);
+
+ my_png_read_frame_head(png_ptr, info_ptr);
+
+ if(my_png_get_valid(png_ptr, info_ptr, PNG_INFO_fcTL))
+ {
+ my_png_get_next_frame_fcTL(png_ptr, info_ptr,
+ &next_frame_width, &next_frame_height,
+ &next_frame_x_offset, &next_frame_y_offset,
+ &next_frame_delay_num, &next_frame_delay_den,
+ &next_frame_dispose_op, &next_frame_blend_op);
+ }
+ else
+ {
+ next_frame_width = width;
+ next_frame_height = height;
+ next_frame_x_offset = 0;
+ next_frame_y_offset = 0;
+ next_frame_dispose_op = PNG_DISPOSE_OP_BACKGROUND;
+ next_frame_blend_op = PNG_BLEND_OP_SOURCE;
+ }
+
+ if(!next_frame_delay_den) next_frame_delay_den = 100;
+
+ img.delay = (s32)(((double)next_frame_delay_num / next_frame_delay_den) * 1000);
+
+ if(next_frame_width + next_frame_x_offset > width || next_frame_height + next_frame_y_offset > height)
+ return SQE_R_BADFILE;
+
+ if(!MALLOC_ROWS(&frame, next_frame_width * sizeof(RGBA), next_frame_height))
+ return SQE_R_NOMEMORY;
+
+ my_png_read_image(png_ptr, frame);
+
+ // copy all pixel values including alpha
+ if(!currentImage || next_frame_blend_op == PNG_BLEND_OP_SOURCE)
+ {
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ memcpy(cur[j]+next_frame_x_offset*sizeof(RGBA), frame[i], next_frame_width * sizeof(RGBA));
+ }
+ else // over
+ {
+ RGBA *src, *dst;
+
+ for(u32 j = next_frame_y_offset,i = 0;i < next_frame_height;j++,i++)
+ {
+ src = (RGBA *)frame[i];
+ dst = (RGBA *)(cur[j]+next_frame_x_offset*sizeof(RGBA));
+ u32 k = next_frame_width;
+
+ while(k--)
+ {
+ // fully transparent foreground
+ if(src->a == 0)
+ ;
+ else if(src->a == 255 || dst->a == 0)
+ *dst = *src;
+ else // composite
+ {
+ dst->r = ((src->a * (src->r - dst->r))>>8) + dst->r;
+ dst->g = ((src->a * (src->g - dst->g))>>8) + dst->g;
+ dst->b = ((src->a * (src->b - dst->b))>>8) + dst->b;
+ //dst->a = ((src->a * (src->a - dst->a))>>8) + dst->a;
+ }
+
+ src++;
+ dst++;
+ }
+ }
+ }
+ }
+
+ finfo.image.push_back(img);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+
+ line++;
+
+ if(zerror || setjmp(png_jmpbuf(png_ptr)))
+ {
+ zerror = true;
+ return SQE_R_BADFILE;
+ }
+
+ if(finfo.animated)
+ memcpy(scan, cur[line], im->w * sizeof(RGBA));
+ else
+ my_png_read_row(png_ptr, (png_bytep)scan, png_bytep_NULL);
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(png_ptr) my_png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+
+ if(fptr) fclose(fptr);
+
+ FREE_ROWS(&frame, next_frame_height);
+ FREE_ROWS(&prev, height);
+ FREE_ROWS(&cur, height);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#ifdef CODEC_PNG
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = true;
+ opt->compression_scheme = CompressionInternal;
+ opt->compression_min = 1;
+ opt->compression_max = 9;
+ opt->compression_def = 7;
+ opt->passes = 8;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ m_png_ptr = 0;
+ m_info_ptr = 0;
+ m_fptr = 0;
+ m_zerror = false;
+
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ m_fptr = fopen(file.c_str(), "wb");
+
+ if(!m_fptr)
+ return SQE_W_NOFILE;
+
+ m_png_ptr = my_png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+
+ if(!m_png_ptr)
+ {
+ m_zerror = true;
+ return SQE_W_NOMEMORY;
+ }
+
+ m_info_ptr = my_png_create_info_struct(m_png_ptr);
+
+ if(!m_info_ptr)
+ {
+ m_zerror = true;
+ return SQE_W_NOMEMORY;
+ }
+
+ if(setjmp(png_jmpbuf(m_png_ptr)))
+ {
+ m_zerror = true;
+ return SQE_W_ERROR;
+ }
+
+ my_png_init_io(m_png_ptr, m_fptr);
+
+ my_png_set_IHDR(m_png_ptr, m_info_ptr, writeimage.w, writeimage.h, 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ ((writeopt.interlaced) ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE),
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_color_8 sig_bit;
+
+ sig_bit.red = 8;
+ sig_bit.green = 8;
+ sig_bit.blue = 8;
+ sig_bit.alpha = 8;
+
+ my_png_set_sBIT(m_png_ptr, m_info_ptr, &sig_bit);
+
+ s32 factor = (writeopt.compression_level < 1 || writeopt.compression_level > 9) ? 1 : writeopt.compression_level;
+
+ my_png_set_compression_level(m_png_ptr, factor);
+
+ my_png_write_info(m_png_ptr, m_info_ptr);
+
+ my_png_set_shift(m_png_ptr, &sig_bit);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ my_png_set_swap(m_png_ptr);
+
+ my_png_set_packswap(m_png_ptr);
+
+ my_png_set_interlace_handling(m_png_ptr);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ if(m_zerror || setjmp(png_jmpbuf(m_png_ptr)))
+ {
+ m_zerror = true;
+ return SQE_W_ERROR;
+ }
+
+ m_row_pointer = (png_bytep)scan;
+
+ my_png_write_rows(m_png_ptr, &m_row_pointer, 1);
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ if(m_png_ptr && !m_zerror) my_png_write_end(m_png_ptr, m_info_ptr);
+ if(m_png_ptr) my_png_destroy_write_struct(&m_png_ptr, &m_info_ptr);
+ if(m_fptr) fclose(m_fptr);
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("png");
+}
+
+#endif
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_svg/fmt_codec_png_defs.h b/kernel/kls_svg/fmt_codec_png_defs.h
new file mode 100644
index 0000000..afef4ac
--- /dev/null
+++ b/kernel/kls_svg/fmt_codec_png_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_png
+#define KSQUIRREL_READ_IMAGE_png
+
+// Nothing to define at this moment :)
+
+#endif
diff --git a/kernel/kls_svg/ksquirrel-libs-svg2png.in b/kernel/kls_svg/ksquirrel-libs-svg2png.in
new file mode 100644
index 0000000..b921e6d
--- /dev/null
+++ b/kernel/kls_svg/ksquirrel-libs-svg2png.in
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+kls_svg_i=""
+kls_svg_o=""
+kls_svg_bin=""
+kls_svg_params=""
+
+while [ "$1" ] ; do
+
+ case "$1" in
+ "--input") kls_svg_i="$2" shift ;;
+ "--output") kls_svg_o="$2" shift ;;
+ "--binary") kls_svg_bin="$2" shift ;;
+ *) kls_svg_params="$kls_svg_params $1" ;;
+ esac
+
+shift
+done
+
+$kls_svg_bin $kls_svg_params "$kls_svg_i" > "$kls_svg_o" \ No newline at end of file
diff --git a/kernel/kls_svg/libkls_svg.so.ui b/kernel/kls_svg/libkls_svg.so.ui
new file mode 100644
index 0000000..cd454c9
--- /dev/null
+++ b/kernel/kls_svg/libkls_svg.so.ui
@@ -0,0 +1,120 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Form1</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>287</width>
+ <height>63</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>no_spinBox</cstring>
+ </property>
+ <property name="suffix">
+ <string>x</string>
+ </property>
+ <property name="maxValue">
+ <number>10</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>scale</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>10</number>
+ </property>
+ <property name="pageStep">
+ <number>2</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Scaling factor:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>scale</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_spinBox</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_spinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>scale</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kernel/kls_tga/Makefile.am b/kernel/kls_tga/Makefile.am
new file mode 100644
index 0000000..c7b8423
--- /dev/null
+++ b/kernel/kls_tga/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_tga.la
+
+libkls_tga_la_SOURCES = fmt_codec_tga.cpp fmt_codec_tga_defs.h
+
+libkls_tga_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_tga_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_tga/fmt_codec_tga.cpp b/kernel/kls_tga/fmt_codec_tga.cpp
new file mode 100644
index 0000000..8a79229
--- /dev/null
+++ b/kernel/kls_tga/fmt_codec_tga.cpp
@@ -0,0 +1,411 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_tga_defs.h"
+#include "fmt_codec_tga.h"
+
+#include "../xpm/codec_tga.xpm"
+
+/*
+ *
+ * The TGA (Truevision Graphics Adapter) format
+ * is used widely in paint, graphics, and imaging applications that
+ * require the storage of image data containing up to 32 bits per
+ * pixel. TGA is associated with the Truevision
+ * product line of Targa, Vista, NuVista, and Targa 2000 graphics
+ * adapters for the PC and Macintosh, all of which can capture
+ * NTSC and/or PAL video image signals and store them in a digital frame buffer.
+ * For this reason, TGA has also become popular in the world of
+ * still-video editing.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.7.2";
+ o->name = "TarGA";
+ o->filter = "*.tga ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-targa";
+ o->pixmap = codec_tga;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ pal_entr = 0;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!frs.readK(&tfh, sizeof(TGA_FILEHEADER))) return SQE_R_BADFILE;
+
+ image.w = tfh.ImageSpecW;
+ image.h = tfh.ImageSpecH;
+ image.bpp = tfh.ImageSpecDepth;
+ pal_entr = 0;
+
+ if(tfh.IDlength)
+ {
+ s8 data[tfh.IDlength];
+
+ if(!frs.readK(data, tfh.IDlength)) return SQE_R_BADFILE;
+
+ fmt_metaentry mt;
+
+ mt.group = "TGA image identification field";
+
+ mt.data = data;
+
+ addmeta(mt);
+ }
+
+ if(tfh.ColorMapType)
+ {
+ pal_entr = tfh.ColorMapSpecLength;
+
+// if((pal = (RGB*)calloc(pal_entr, sizeof(RGB))) == 0)
+// return SQE_R_NOMEMORY;
+
+// s8 sz = tfh.ColorMapSpecEntrySize;
+ s32 i;
+// u16 word;
+
+ for(i = 0;i < pal_entr;i++)
+ {
+ /*if(sz==24)*/ if(!frs.readK(pal+i, sizeof(RGB))) return SQE_R_BADFILE;
+/* alpha ingored *//*else if(sz==32) { fread(finfo.pal+i, sizeof(RGB), 1, fptr); fgetc(fptr); }
+ else if(sz==16)
+ {
+ fread(&word, 2, 1, fptr);
+ (finfo.pal)[i].b = (word&0x1f) << 3;
+ (finfo.pal)[i].g = ((word&0x3e0) >> 5) << 3;
+ (finfo.pal)[i].r = ((word&0x7c00)>>10) << 3;
+ }*/
+
+ }
+ }
+// else
+// pal = 0;
+
+ if(tfh.ImageType == 0)
+ return SQE_R_BADFILE;
+
+ std::string comp, type;
+
+ fliph = (bool)(tfh.ImageSpecDescriptor & 0x10);
+ image.needflip = !(bool)(tfh.ImageSpecDescriptor & 0x20);
+ image.hasalpha = (image.bpp == 32);
+
+ switch(tfh.ImageType)
+ {
+ case 1:
+ comp = "-";
+ type = "Color indexed";
+ break;
+
+ case 2:
+ comp = "-";
+ type = (( image.bpp == 32) ? "RGBA":"RGB");
+ break;
+
+ case 3:
+ comp = "-";
+ type = "Monochrome";
+ break;
+
+ case 9:
+ comp = "RLE";
+ type = "Color indexed";
+ break;
+
+ case 10:
+ comp = "RLE";
+ type = (( image.bpp == 32) ? "RGBA":"RGB");
+ break;
+
+ case 11:
+ comp = "RLE";
+ type = "Monochrome";
+ break;
+ }
+
+ image.compression = comp;
+ image.colorspace = type;
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ s32 j, counter = 0;
+ RGB rgb;
+ RGBA rgba;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(tfh.ImageType)
+ {
+ case 0:
+ break;
+
+ case 1:
+ {
+ }
+ break;
+
+ case 2:
+ {
+ if(tfh.ImageSpecDepth==24)
+ {
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ (scan+counter)->r = rgb.b;
+ (scan+counter)->g = rgb.g;
+ (scan+counter)->b = rgb.r;
+ counter++;
+ }
+ }
+ else if(tfh.ImageSpecDepth==32)
+ {
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ (scan+counter)->r = rgba.b;
+ (scan+counter)->g = rgba.g;
+ (scan+counter)->b = rgba.r;
+ counter++;
+ }
+ }
+ else if(tfh.ImageSpecDepth==16)
+ {
+ u16 word;
+
+ for(j = 0;j < im->w;j++)
+ {
+ if(!frs.readK(&word, 2)) return SQE_R_BADFILE;
+
+ scan[counter].b = (word&0x1f) << 3;
+ scan[counter].g = ((word&0x3e0) >> 5) << 3;
+ scan[counter++].r = ((word&0x7c00)>>10) << 3;
+ }
+ }
+ }
+ break;
+
+ case 3:
+ break;
+
+ // RLE + color mapped
+ case 9:
+ break;
+
+ // RLE + true color
+ case 10:
+ {
+ u8 bt, count;
+ ushort counter = 0, word;
+ RGBA rgba;
+
+ for(;;)
+ {
+ if(!frs.readK(&bt, 1)) return SQE_R_BADFILE;
+
+ count = (bt&127) + 1;
+
+ // RLE packet
+ if(bt >= 128)
+ {
+ switch(im->bpp)
+ {
+ case 16:
+ if(!frs.readK(&word, 2)) return SQE_R_BADFILE;
+
+ rgb.b = (word&0x1f) << 3;
+ rgb.g = ((word&0x3e0) >> 5) << 3;
+ rgb.r = ((word&0x7c00)>>10) << 3;
+
+ for(j = 0;j < count;j++)
+ {
+ memcpy(scan+(counter++), &rgb, sizeof(RGB));
+ if(counter >= im->w-1) goto lts;
+ }
+ break;
+
+ case 24:
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ for(j = 0;j < count;j++)
+ {
+ (scan+counter)->r = rgb.b;
+ (scan+counter)->g = rgb.g;
+ (scan+counter)->b = rgb.r;
+ counter++;
+
+ if(counter >= im->w-1) goto lts;
+ }
+ break;
+
+ case 32:
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ for(j = 0;j < count;j++)
+ {
+ (scan+counter)->r = rgba.b;
+ (scan+counter)->g = rgba.g;
+ (scan+counter)->b = rgba.r;
+ counter++;
+
+ if(counter >= im->w-1) goto lts;
+ }
+ break;
+ }
+ }
+ else // Raw packet
+ {
+ switch(im->bpp)
+ {
+ case 16:
+
+ for(j = 0;j < count;j++)
+ {
+ if(!frs.readK(&word, 2)) return SQE_R_BADFILE;
+
+ rgb.b = (word&0x1f) << 3;
+ rgb.g = ((word&0x3e0) >> 5) << 3;
+ rgb.r = ((word&0x7c00)>>10) << 3;
+
+ memcpy(scan+(counter++), &rgb, sizeof(RGB));
+ if(counter >= im->w-1) goto lts;
+ }
+ break;
+
+ case 24:
+ for(j = 0;j < count;j++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ (scan+counter)->r = rgb.b;
+ (scan+counter)->g = rgb.g;
+ (scan+counter)->b = rgb.r;
+ counter++;
+
+ if(counter >= im->w-1) goto lts;
+ }
+ break;
+
+ case 32:
+ for(j = 0;j < count;j++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ (scan+counter)->r = rgba.b;
+ (scan+counter)->g = rgba.g;
+ (scan+counter)->b = rgba.r;
+ counter++;
+ if(counter >= im->w-1) goto lts;
+ }
+ break;
+ }
+ }
+ }
+ }
+ lts:
+ break;
+
+ // RLE + B&W
+ case 11:
+ break;
+ }
+
+ if(fliph)
+ {
+ RGBA t;
+ s32 ww = im->w;
+
+ for(j = 0;j < ww / 2;j++)
+ {
+ t = *(scan+j);
+ *(scan+j) = *(scan+ww-j-1);
+ *(scan+ww-j-1) = t;
+ }
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_tga/fmt_codec_tga_defs.h b/kernel/kls_tga/fmt_codec_tga_defs.h
new file mode 100644
index 0000000..4cc7f52
--- /dev/null
+++ b/kernel/kls_tga/fmt_codec_tga_defs.h
@@ -0,0 +1,70 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_tga
+#define KSQUIRREL_READ_IMAGE_tga
+
+struct TGA_FILEHEADER
+{
+ u8 IDlength;
+ u8 ColorMapType; /* 1==we have colormap, 0==no */
+ u8 ImageType;
+ /* 0==no image data
+ 1==uncompressed+color map
+ 2==uncompressed+true color
+ 3==uncompressed+B&W
+ 9==RLE+color map
+ 10==RLE+true color
+ 11==RLE+B&W
+ */
+ u16 ColorMapSpecFirstEntryIndex;
+ u16 ColorMapSpecLength;
+ u8 ColorMapSpecEntrySize; /* 15,16,24,32 */
+ u16 ImageSpecX;
+ u16 ImageSpecY;
+ u16 ImageSpecW;
+ u16 ImageSpecH;
+ u8 ImageSpecDepth; /* 8 or 16 or 24 or 32 */
+ u8 ImageSpecDescriptor; /* 7 6 5 4 3 2 1 0 */
+
+}PACKED;
+
+struct TGA_IMAGEDATA
+{
+ u8 *ID; /* length of this == TGA_FILEHEADER::IDlength */
+ u8 *ColorMapData; /* -//- */
+ u8 *Image; /* widthxheigth pixels */
+
+}PACKED;
+
+struct TGA_FOOTER
+{
+ u32 ExtensionAreaOffset;
+ u32 DeveloperDirectoryOffset;
+ u8 Signature[16]; /* "TRUEVISION-XFILE" */
+ u8 punct; /* '.' */
+ u8 TGAnull; /* 0x0 */
+
+}PACKED;
+
+/* we'll skip "developer area" & "extension area", we don't need to read them. */
+
+#endif
diff --git a/kernel/kls_tiff/Makefile.am b/kernel/kls_tiff/Makefile.am
new file mode 100644
index 0000000..822a862
--- /dev/null
+++ b/kernel/kls_tiff/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_tiff.la
+
+libkls_tiff_la_SOURCES = fmt_codec_tiff.cpp fmt_codec_tiff_defs.h
+
+libkls_tiff_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_tiff_la_LIBADD = ${SQ_LOCAL_RPATH} -ltiff
+
+EXTRA_DIST = libkls_tiff.so.ui
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 libkls_tiff.so.ui $(DESTDIR)$(pkgdatadir)/libkls_tiff.so.ui
+
+AM_CXXFLAGS = -DTIFF_UI=\"${pkgdatadir}/libkls_tiff.so.ui\"
diff --git a/kernel/kls_tiff/fmt_codec_tiff.cpp b/kernel/kls_tiff/fmt_codec_tiff.cpp
new file mode 100644
index 0000000..e22cb70
--- /dev/null
+++ b/kernel/kls_tiff/fmt_codec_tiff.cpp
@@ -0,0 +1,298 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include <tiffio.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_tiff_defs.h"
+#include "fmt_codec_tiff.h"
+
+#include "../xpm/codec_tiff.xpm"
+
+/*
+ *
+ * The TIFF specification was originally released in
+ * 1986 by Aldus Corporation as a standard method of storing
+ * black-and-white images created by scanners and desktop publishing
+ * applications. This first public release of TIFF was
+ * the third major revision of the TIFF format, and
+ * although it was not assigned a specific version number, this release
+ * may be thought of as TIFF Revision 3.0. The first
+ * widely used revision of TIFF, 4.0, was released in
+ * April 1987. TIFF 4.0 added support for uncompressed
+ * RGB color images and was quickly followed by the
+ * release of TIFF Revision 5.0 in August
+ * 1988. TIFF 5.0 was the first revision to add the
+ * capability of storing palette color images and support for the
+ * LZW compression algorithm. TIFF 6.0 was released in June
+ * 1992 and added support for CMYK and YCbCr color
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{
+ compr[COMPRESSION_NONE] = "None";
+ compr[COMPRESSION_CCITTRLE] = "CCITTRLE";
+ compr[COMPRESSION_CCITTFAX3] = "CCITTFAX3";
+ compr[COMPRESSION_CCITT_T4] = "CCITT_T4";
+ compr[COMPRESSION_CCITTFAX4] = "CCITTFAX4";
+ compr[COMPRESSION_CCITT_T6] = "CCITT_T6";
+ compr[COMPRESSION_LZW] = "LZW";
+ compr[COMPRESSION_OJPEG] = "OJPEG";
+ compr[COMPRESSION_JPEG] = "JPEG";
+ compr[COMPRESSION_NEXT] = "NEXT";
+ compr[COMPRESSION_CCITTRLEW] = "CCITTRLEW";
+ compr[COMPRESSION_PACKBITS] = "PACKBITS";
+ compr[COMPRESSION_THUNDERSCAN] = "THUNDERSCAN";
+ compr[COMPRESSION_IT8CTPAD] = "IT8CTPAD";
+ compr[COMPRESSION_IT8LW] = "IT8LW";
+ compr[COMPRESSION_IT8MP] = "IT8MP";
+ compr[COMPRESSION_IT8BL] = "IT8BL";
+ compr[COMPRESSION_PIXARFILM] = "PIXARFILM";
+ compr[COMPRESSION_PIXARLOG] = "PIXARLOG";
+ compr[COMPRESSION_DEFLATE] = "DEFLATE";
+ compr[COMPRESSION_ADOBE_DEFLATE] = "Adobe DEFLATE";
+ compr[COMPRESSION_DCS] = "DCS";
+ compr[COMPRESSION_JBIG] = "JBIG";
+ compr[COMPRESSION_SGILOG] = "SGILOG";
+ compr[COMPRESSION_SGILOG24] = "SGILOG24";
+ compr[COMPRESSION_JP2000] = "JP2000";
+}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "1.0.1";
+ o->name = "Tagged Image File Format";
+ o->filter = "*.tif *.tiff ";
+ o->config = std::string(TIFF_UI);
+ o->mime = "";
+ o->mimetype = "image/tiff";
+ o->pixmap = codec_tiff;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 1;
+
+ m_settings["pages"] = val;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ currentImage = -1;
+
+ if((ftiff = TIFFOpen(file.c_str(), "r")) == NULL)
+ return SQE_R_BADFILE;
+
+ TIFFSetWarningHandler(NULL);
+ TIFFSetErrorHandler(NULL);
+
+ finfo.animated = false;
+
+ fmt_settings::iterator it = m_settings.find("pages");
+
+ pages = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(pages < 1 || pages > 1000)
+ pages = 1;
+
+ dircount = 0;
+
+ while(TIFFReadDirectory(ftiff))
+ dircount++;
+
+ TIFFSetDirectory(ftiff, 0);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == pages)
+ return SQE_NOTOK;
+
+ if(dircount)
+ {
+ if(currentImage == dircount)
+ return SQE_NOTOK;
+ }
+ else
+ if(currentImage)
+ return SQE_NOTOK;
+
+ if(dircount != 1 && dircount != 0)
+ if(!TIFFReadDirectory(ftiff))
+ return SQE_R_BADFILE;
+
+ if(currentImage)
+ TIFFRGBAImageEnd(&img);
+
+ fmt_image image;
+
+ s32 bps, spp;
+
+ TIFFGetField(ftiff, TIFFTAG_IMAGEWIDTH, &image.w);
+ TIFFGetField(ftiff, TIFFTAG_IMAGELENGTH, &image.h);
+
+ memset(&img, 0, sizeof(TIFFRGBAImage));
+
+ TIFFRGBAImageBegin(&img, ftiff, 1, 0);
+
+ bps = img.bitspersample;
+ spp = img.samplesperpixel;
+
+ s16 cmp;
+ TIFFGetField(ftiff, TIFFTAG_COMPRESSION, &cmp);
+ std::map<s32, std::string>::iterator it = compr.find(cmp);
+
+ image.bpp = bps * spp;
+ image.compression = (it == compr.end() ? "Unknown" : (*it).second);
+ image.hasalpha = true;
+ image.colorspace = fmt_utils::colorSpaceByBpp(image.bpp);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ const s32 W = im->w * sizeof(RGBA);
+
+ uint32 buf[W];
+
+ TIFFRGBAImageGet(&img, buf, im->w, 1);
+
+ memcpy(scan, buf, W);
+
+ img.row_offset++;
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ TIFFRGBAImageEnd(&img);
+ TIFFClose(ftiff);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionRLE;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ out = TIFFOpen(file.c_str(), "w");
+
+ if(!out)
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ TIFFSetField(out, TIFFTAG_IMAGEWIDTH, writeimage.w);
+ TIFFSetField(out, TIFFTAG_IMAGELENGTH, writeimage.h);
+ TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+ TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 4);
+ TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
+ TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ TIFFSetField(out, TIFFTAG_COMPRESSION, (writeopt.compression_scheme == CompressionRLE ? COMPRESSION_PACKBITS : COMPRESSION_NONE));
+ TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, (uint32) -1));
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ ++line;
+
+ if(TIFFWriteScanline(out, (u8 *)scan, line, 0) < 0)
+ return SQE_W_ERROR;
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ TIFFClose(out);
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("tiff");
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_tiff/fmt_codec_tiff_defs.h b/kernel/kls_tiff/fmt_codec_tiff_defs.h
new file mode 100644
index 0000000..bc625a1
--- /dev/null
+++ b/kernel/kls_tiff/fmt_codec_tiff_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_tiff
+#define KSQUIRREL_READ_IMAGE_tiff
+
+// Nothing to define
+
+#endif
diff --git a/kernel/kls_tiff/libkls_tiff.so.ui b/kernel/kls_tiff/libkls_tiff.so.ui
new file mode 100644
index 0000000..c7275da
--- /dev/null
+++ b/kernel/kls_tiff/libkls_tiff.so.ui
@@ -0,0 +1,135 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Form1</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>313</width>
+ <height>74</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Read no more than ... pages:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>pages</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>40</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>no_pages</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>pages</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>no_pages</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>no_pages</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>pages</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kernel/kls_ttf/Makefile.am b/kernel/kls_ttf/Makefile.am
new file mode 100644
index 0000000..10d2efe
--- /dev/null
+++ b/kernel/kls_ttf/Makefile.am
@@ -0,0 +1,19 @@
+SUBDIRS = ftview
+
+INCLUDES = -I../include -Iftview @SQ_FT_CFLAGS@
+
+bin_PROGRAMS = ksquirrel-libs-ttf2pnm
+
+ksquirrel_libs_ttf2pnm_SOURCES = ttf2pnm.cpp ftcommon.cpp
+
+ksquirrel_libs_ttf2pnm_LDADD = @SQ_FT_LDFLAGS@ -Lftview -lftview
+
+pkglib_LTLIBRARIES = libkls_ttf.la
+
+libkls_ttf_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_ttf_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_ttf_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_TTF -DTTF2PNM=\"${bindir}/ksquirrel-libs-ttf2pnm\"
diff --git a/kernel/kls_ttf/fmt_codec_pnm.cpp b/kernel/kls_ttf/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_ttf/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_ttf/fmt_codec_pnm_defs.h b/kernel/kls_ttf/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_ttf/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_ttf/ftcommon.cpp b/kernel/kls_ttf/ftcommon.cpp
new file mode 100644
index 0000000..d162452
--- /dev/null
+++ b/kernel/kls_ttf/ftcommon.cpp
@@ -0,0 +1,1333 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 2005, 2006 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* */
+/* ftcommon.c - common routines for the FreeType demo programs. */
+/* */
+/****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include FT_CACHE_H
+#include FT_CACHE_MANAGER_H
+
+#include FT_BITMAP_H
+
+#include "ftcommon.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+ FT_Error error;
+
+ /* PanicZ */
+ void
+ PanicZ( const char * )
+ {
+ /*fprintf( stderr, "%s\n error = 0x%04x\n", message, error );*/
+ exit( 1 );
+ }
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** DISPLAY-SPECIFIC DEFINITIONS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#define DIM_X 600
+#define DIM_Y 450
+
+ grBitmap*
+ FTDemo_Display_New(void)
+ {
+ grBitmap *bit = (grBitmap *)malloc(sizeof(grBitmap));
+
+ if(!bit)
+ return NULL;
+
+ bit->mode = gr_pixel_mode_rgb24;
+ bit->width = DIM_X;
+ bit->rows = DIM_Y;
+ bit->grays = 256;
+
+ grNewBitmap(bit->mode, bit->grays, bit->width, bit->rows, bit);
+
+ grSetGlyphGamma(1.0);
+
+ return bit;
+ }
+
+
+ void
+ FTDemo_Display_Done(grBitmap *bit)
+ {
+ grDoneBitmap(bit);
+ }
+
+ void
+ FTDemo_Display_Clear(grBitmap *bit)
+ {
+ int image_size = bit->width * bit->rows * 3;
+
+ memset(bit->buffer, 255, image_size);
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** FREETYPE-SPECIFIC DEFINITIONS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+#define FLOOR( x ) ( (x) & -64 )
+#define CEIL( x ) ( ( (x) + 63 ) & -64 )
+#define ROUND( x ) ( ( (x) + 32 ) & -64 )
+#define TRUNC( x ) ( (x) >> 6 )
+
+
+
+ static
+ const char* file_suffixes[] =
+ {
+ ".ttf",
+ ".ttc",
+ ".otf",
+ ".pfa",
+ ".pfb",
+ 0
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* The face requester is a function provided by the client application */
+ /* to the cache manager, whose role is to translate an `abstract' face */
+ /* ID into a real FT_Face object. */
+ /* */
+ /* In this program, the face IDs are simply pointers to TFont objects. */
+ /* */
+ static FT_Error
+ my_face_requester( FTC_FaceID face_id,
+ FT_Library lib,
+ FT_Pointer request_data,
+ FT_Face* aface )
+ {
+ PFont font = (PFont)face_id;
+
+ FT_UNUSED( request_data );
+
+ if ( font->file_address != NULL )
+ error = FT_New_Memory_Face( lib, (FT_Byte*)font->file_address, font->file_size,
+ font->face_index, aface );
+ else
+ error = FT_New_Face( lib,
+ font->filepathname,
+ font->face_index,
+ aface );
+ if ( !error )
+ {
+ const char* suffix_rchr;
+ char orig[4];
+
+ suffix_rchr = strrchr( font->filepathname, '.' );
+ char* suffix = new char[strlen(font->filepathname) + 1];
+ strcpy(suffix, suffix_rchr);
+
+ if ( suffix && ( strcasecmp( suffix, ".pfa" ) == 0 ||
+ strcasecmp( suffix, ".pfb" ) == 0 ) )
+ {
+ suffix++;
+
+ memcpy( orig, suffix, 4 );
+ memcpy( suffix, "afm", 4 );
+ FT_Attach_File( *aface, font->filepathname );
+
+ memcpy( suffix, "pfm", 4 );
+ FT_Attach_File( *aface, font->filepathname );
+ memcpy( suffix, orig, 4 );
+ }
+
+ if ( (*aface)->charmaps )
+ (*aface)->charmap = (*aface)->charmaps[font->cmap_index];
+ }
+
+ return error;
+ }
+
+
+ FTDemo_Handle*
+ FTDemo_New( FT_Encoding encoding )
+ {
+ FTDemo_Handle* handle;
+
+
+ handle = (FTDemo_Handle *)malloc( sizeof( FTDemo_Handle ) );
+ if ( !handle )
+ return NULL;
+
+ memset( handle, 0, sizeof( FTDemo_Handle ) );
+
+ error = FT_Init_FreeType( &handle->library );
+ if ( error )
+ PanicZ( "could not initialize FreeType" );
+
+ error = FTC_Manager_New( handle->library, 0, 0, 0,
+ my_face_requester, 0, &handle->cache_manager );
+ if ( error )
+ PanicZ( "could not initialize cache manager" );
+
+ error = FTC_SBitCache_New( handle->cache_manager, &handle->sbits_cache );
+ if ( error )
+ PanicZ( "could not initialize small bitmaps cache" );
+
+ error = FTC_ImageCache_New( handle->cache_manager, &handle->image_cache );
+ if ( error )
+ PanicZ( "could not initialize glyph image cache" );
+
+ error = FTC_CMapCache_New( handle->cache_manager, &handle->cmap_cache );
+ if ( error )
+ PanicZ( "could not initialize charmap cache" );
+
+
+ FT_Bitmap_New( &handle->bitmap );
+
+ handle->encoding = encoding;
+
+ handle->hinted = 1;
+ handle->antialias = 1;
+ handle->use_sbits = 1;
+ handle->low_prec = 0;
+ handle->autohint = 0;
+ handle->lcd_mode = 0;
+
+ handle->use_sbits_cache = 1;
+
+ /* string_init */
+ memset( handle->string, 0, sizeof( TGlyph ) * MAX_GLYPHS );
+ handle->string_length = 0;
+ handle->string_reload = 1;
+
+ return handle;
+ }
+
+
+ void
+ FTDemo_Done( FTDemo_Handle* handle )
+ {
+ int i;
+
+
+ for ( i = 0; i < handle->max_fonts; i++ )
+ {
+ if ( handle->fonts[i] )
+ {
+ if ( handle->fonts[i]->filepathname )
+ free( (void*)handle->fonts[i]->filepathname );
+ free( handle->fonts[i] );
+ }
+ }
+ free( handle->fonts );
+
+ /* string_done */
+ for ( i = 0; i < MAX_GLYPHS; i++ )
+ {
+ PGlyph glyph = handle->string + i;
+
+
+ if ( glyph->image )
+ FT_Done_Glyph( glyph->image );
+ }
+
+ FT_Bitmap_Done( handle->library, &handle->bitmap );
+ FTC_Manager_Done( handle->cache_manager );
+ FT_Done_FreeType( handle->library );
+
+ free( handle );
+ }
+
+
+ FT_Error
+ FTDemo_Install_Font( FTDemo_Handle* handle,
+ const char* filepath )
+ {
+ static char filename[1024 + 5];
+ int i, len, num_faces;
+ FT_Face face;
+
+
+ len = strlen( filepath );
+ if ( len > 1024 )
+ len = 1024;
+
+ strncpy( filename, filepath, len );
+ filename[len] = 0;
+
+ error = FT_New_Face( handle->library, filename, 0, &face );
+
+#ifndef macintosh
+ /* could not open the file directly; we will now try various */
+ /* suffixes like `.ttf' or `.pfb' */
+ if ( error )
+ {
+ const char** suffix;
+ char* p;
+ int found = 0;
+
+ suffix = file_suffixes;
+ p = filename + len - 1;
+
+ while ( p >= filename && *p != '\\' && *p != '/' )
+ {
+ if ( *p == '.' )
+ break;
+
+ p--;
+ }
+
+ /* no suffix found */
+ if ( p < filename || *p != '.' )
+ p = filename + len;
+
+ for ( suffix = file_suffixes; suffix[0]; suffix++ )
+ {
+ /* try with current suffix */
+ strcpy( p, suffix[0] );
+
+ error = FT_New_Face( handle->library, filename, 0, &face );
+ if ( !error )
+ {
+ found = 1;
+
+ break;
+ }
+ }
+
+ /* really couldn't open this file */
+ if ( !found )
+ return error;
+ }
+#endif /* !macintosh */
+
+ /* allocate new font object */
+ num_faces = face->num_faces;
+ for ( i = 0; i < num_faces; i++ )
+ {
+ PFont font;
+
+
+ if ( i > 0 )
+ {
+ error = FT_New_Face( handle->library, filename, i, &face );
+ if ( error )
+ continue;
+ }
+
+ if ( handle->encoding != FT_ENCODING_NONE )
+ {
+ error = FT_Select_Charmap( face, handle->encoding );
+ if ( error )
+ {
+ FT_Done_Face( face );
+ return error;
+ }
+ }
+
+ font = (PFont)malloc( sizeof ( *font ) );
+
+ font->filepathname = (char*)malloc( strlen( filename ) + 1 );
+ strcpy( (char*)font->filepathname, filename );
+
+ font->face_index = i;
+ font->cmap_index = face->charmap ? FT_Get_Charmap_Index( face->charmap )
+ : 0;
+
+ if ( handle->preload )
+ {
+ FILE* file = fopen( filename, "rb" );
+ size_t file_size;
+
+ if ( file == NULL ) /* shouldn't happen */
+ {
+ free( font );
+ return FT_Err_Invalid_Argument;
+ }
+
+ fseek( file, 0, SEEK_END );
+ file_size = ftell( file );
+ fseek( file, 0, SEEK_SET );
+
+ font->file_address = malloc( file_size );
+ fread( font->file_address, 1, file_size, file );
+
+ font->file_size = file_size;
+
+ fclose( file );
+ }
+ else
+ {
+ font->file_address = NULL;
+ font->file_size = 0;
+ }
+
+ switch ( handle->encoding )
+ {
+ case FT_ENCODING_NONE:
+ font->num_indices = face->num_glyphs;
+ break;
+
+ case FT_ENCODING_UNICODE:
+ font->num_indices = 0x110000L;
+ break;
+
+ case FT_ENCODING_MS_SYMBOL:
+ case FT_ENCODING_ADOBE_LATIN_1:
+ case FT_ENCODING_ADOBE_STANDARD:
+ case FT_ENCODING_ADOBE_EXPERT:
+ case FT_ENCODING_ADOBE_CUSTOM:
+ case FT_ENCODING_APPLE_ROMAN:
+ font->num_indices = 0x100L;
+ break;
+
+ default:
+ font->num_indices = 0x10000L;
+ }
+
+ FT_Done_Face( face );
+ face = NULL;
+
+ if ( handle->max_fonts == 0 )
+ {
+ handle->max_fonts = 16;
+ handle->fonts = (PFont*)calloc( handle->max_fonts,
+ sizeof ( PFont ) );
+ }
+ else if ( handle->num_fonts >= handle->max_fonts )
+ {
+ handle->max_fonts *= 2;
+ handle->fonts = (PFont*)realloc( handle->fonts,
+ handle->max_fonts *
+ sizeof ( PFont ) );
+
+ memset( &handle->fonts[handle->num_fonts], 0,
+ ( handle->max_fonts - handle->num_fonts ) *
+ sizeof ( PFont ) );
+ }
+
+ handle->fonts[handle->num_fonts++] = font;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ void
+ FTDemo_Set_Current_Font( FTDemo_Handle* handle,
+ PFont font )
+ {
+ handle->current_font = font;
+ handle->image_type.face_id = (FTC_FaceID)font;
+
+ handle->string_reload = 1;
+ }
+
+
+ void
+ FTDemo_Set_Current_Size( FTDemo_Handle* handle,
+ int pixel_size )
+ {
+ if ( pixel_size > 0xFFFF )
+ pixel_size = 0xFFFF;
+
+ handle->image_type.width = (FT_UShort)pixel_size;
+ handle->image_type.height = (FT_UShort)pixel_size;
+
+ handle->string_reload = 1;
+ }
+
+ void
+ FTDemo_Set_Preload( FTDemo_Handle* handle,
+ int preload )
+ {
+ handle->preload = !!preload;
+ }
+
+ void
+ FTDemo_Set_Current_Pointsize( FTDemo_Handle* handle,
+ int point_size,
+ int res )
+ {
+ FTDemo_Set_Current_Size( handle, ( point_size * res + 36 ) / 72 );
+ }
+
+
+ void
+ FTDemo_Update_Current_Flags( FTDemo_Handle* handle )
+ {
+ FT_UInt32 flags, target;
+
+ flags = FT_LOAD_DEFAULT; /* really 0 */
+
+ flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
+
+ if ( handle->autohint )
+ flags |= FT_LOAD_FORCE_AUTOHINT;
+
+ if ( !handle->use_sbits )
+ flags |= FT_LOAD_NO_BITMAP;
+
+ if ( handle->hinted )
+ {
+ target = 0;
+
+ if ( handle->antialias )
+ {
+ switch ( handle->lcd_mode )
+ {
+ case LCD_MODE_LIGHT:
+ target = FT_LOAD_TARGET_LIGHT;
+ break;
+
+ case LCD_MODE_RGB:
+ case LCD_MODE_BGR:
+ target = FT_LOAD_TARGET_LCD;
+ break;
+
+ case LCD_MODE_VRGB:
+ case LCD_MODE_VBGR:
+ target = FT_LOAD_TARGET_LCD_V;
+ break;
+
+ default:
+ target = FT_LOAD_TARGET_NORMAL;
+ }
+ }
+ else
+ target = FT_LOAD_TARGET_MONO;
+
+ flags |= target;
+ }
+ else
+ flags |= FT_LOAD_NO_HINTING;
+
+ handle->image_type.flags = flags;
+ handle->string_reload = 1;
+ }
+
+
+ FT_UInt
+ FTDemo_Get_Index( FTDemo_Handle* handle,
+ FT_UInt32 charcode )
+ {
+ FTC_FaceID face_id = handle->image_type.face_id;
+ PFont font = handle->current_font;
+
+
+ return FTC_CMapCache_Lookup( handle->cmap_cache, face_id,
+ font->cmap_index, charcode );
+ }
+
+
+ FT_Error
+ FTDemo_Get_Size( FTDemo_Handle* handle,
+ FT_Size* asize )
+ {
+ FTC_ScalerRec scaler;
+ FT_Size size;
+
+ scaler.face_id = handle->image_type.face_id;
+ scaler.width = handle->image_type.width;
+ scaler.height = handle->image_type.height;
+ scaler.pixel = 1;
+
+ error = FTC_Manager_LookupSize( handle->cache_manager, &scaler, &size );
+
+ if ( !error )
+ *asize = size;
+
+ return error;
+ }
+
+
+ FT_Error
+ FTDemo_Glyph_To_Bitmap( FTDemo_Handle* handle,
+ FT_Glyph glyf,
+ grBitmap* target,
+ int* left,
+ int* top,
+ int* x_advance,
+ int* y_advance,
+ FT_Glyph* aglyf )
+ {
+ FT_BitmapGlyph bitmap;
+ FT_Bitmap* source;
+
+
+ *aglyf = NULL;
+
+ error = FT_Err_Ok;
+
+ if ( glyf->format == FT_GLYPH_FORMAT_OUTLINE )
+ {
+ FT_Render_Mode render_mode = FT_RENDER_MODE_MONO;
+
+
+ if ( handle->antialias )
+ {
+ if ( handle->lcd_mode == 0 )
+ render_mode = FT_RENDER_MODE_NORMAL;
+ else if ( handle->lcd_mode == 1 )
+ render_mode = FT_RENDER_MODE_LIGHT;
+ else if ( handle->lcd_mode <= 3 )
+ render_mode = FT_RENDER_MODE_LCD;
+ else
+ render_mode = FT_RENDER_MODE_LCD_V;
+ }
+
+ /* render the glyph to a bitmap, don't destroy original */
+ error = FT_Glyph_To_Bitmap( &glyf, render_mode, NULL, 0 );
+ if ( error )
+ return error;
+
+ *aglyf = glyf;
+ }
+
+ if ( glyf->format != FT_GLYPH_FORMAT_BITMAP )
+ PanicZ( "invalid glyph format returned!" );
+
+ bitmap = (FT_BitmapGlyph)glyf;
+ source = &bitmap->bitmap;
+
+ target->rows = source->rows;
+ target->width = source->width;
+ target->pitch = source->pitch;
+ target->buffer = source->buffer;
+ target->grays = source->num_grays;
+
+ switch ( source->pixel_mode )
+ {
+ case FT_PIXEL_MODE_MONO:
+ target->mode = gr_pixel_mode_mono;
+ break;
+
+ case FT_PIXEL_MODE_GRAY:
+ target->mode = gr_pixel_mode_gray;
+ target->grays = source->num_grays;
+ break;
+
+ case FT_PIXEL_MODE_GRAY2:
+ case FT_PIXEL_MODE_GRAY4:
+ (void)FT_Bitmap_Convert( handle->library, source, &handle->bitmap, 1 );
+ target->pitch = handle->bitmap.pitch;
+ target->buffer = handle->bitmap.buffer;
+ target->mode = gr_pixel_mode_gray;
+ target->grays = handle->bitmap.num_grays;
+ break;
+
+ case FT_PIXEL_MODE_LCD:
+ target->mode = handle->lcd_mode == 2 ? gr_pixel_mode_lcd
+ : gr_pixel_mode_lcd2;
+ target->grays = source->num_grays;
+ break;
+
+ case FT_PIXEL_MODE_LCD_V:
+ target->mode = handle->lcd_mode == 4 ? gr_pixel_mode_lcdv
+ : gr_pixel_mode_lcdv2;
+ target->grays = source->num_grays;
+ break;
+
+ default:
+ return FT_Err_Invalid_Glyph_Format;
+ }
+
+ *left = bitmap->left;
+ *top = bitmap->top;
+
+ *x_advance = ( glyf->advance.x + 0x8000 ) >> 16;
+ *y_advance = ( glyf->advance.y + 0x8000 ) >> 16;
+
+ return error;
+ }
+
+
+ FT_Error
+ FTDemo_Index_To_Bitmap( FTDemo_Handle* handle,
+ FT_ULong Index,
+ grBitmap* target,
+ int* left,
+ int* top,
+ int* x_advance,
+ int* y_advance,
+ FT_Glyph* aglyf )
+ {
+ int cached_bitmap = 1;
+
+ *aglyf = NULL;
+
+ /* use the SBits cache to store small glyph bitmaps; this is a lot */
+ /* more memory-efficient */
+ /* */
+ if ( handle->use_sbits_cache &&
+ handle->image_type.width < 48 &&
+ handle->image_type.height < 48 )
+ {
+ FTC_SBit sbit;
+ FT_Bitmap source;
+
+
+ error = FTC_SBitCache_Lookup( handle->sbits_cache,
+ &handle->image_type,
+ Index,
+ &sbit,
+ NULL );
+ if ( error )
+ goto Exit;
+
+ if ( sbit->buffer )
+ {
+ target->rows = sbit->height;
+ target->width = sbit->width;
+ target->pitch = sbit->pitch;
+ target->buffer = sbit->buffer;
+ target->grays = sbit->max_grays + 1;
+
+ switch ( sbit->format )
+ {
+ case FT_PIXEL_MODE_MONO:
+ target->mode = gr_pixel_mode_mono;
+ break;
+
+ case FT_PIXEL_MODE_GRAY:
+ target->mode = gr_pixel_mode_gray;
+ target->grays = sbit->max_grays + 1;
+ break;
+
+ case FT_PIXEL_MODE_GRAY2:
+ case FT_PIXEL_MODE_GRAY4:
+ source.rows = sbit->height;
+ source.width = sbit->width;
+ source.pitch = sbit->pitch;
+ source.buffer = sbit->buffer;
+ source.pixel_mode = sbit->format;
+
+ (void)FT_Bitmap_Convert( handle->library, &source,
+ &handle->bitmap, 1 );
+
+ target->pitch = handle->bitmap.pitch;
+ target->buffer = handle->bitmap.buffer;
+ target->mode = gr_pixel_mode_gray;
+ target->grays = handle->bitmap.num_grays;
+
+ cached_bitmap = 0;
+ break;
+
+ case FT_PIXEL_MODE_LCD:
+ target->mode = handle->lcd_mode == 2 ? gr_pixel_mode_lcd
+ : gr_pixel_mode_lcd2;
+ target->grays = sbit->max_grays + 1;
+ break;
+
+ case FT_PIXEL_MODE_LCD_V:
+ target->mode = handle->lcd_mode == 4 ? gr_pixel_mode_lcdv
+ : gr_pixel_mode_lcdv2;
+ target->grays = sbit->max_grays + 1;
+ break;
+
+ default:
+ return FT_Err_Invalid_Glyph_Format;
+ }
+
+
+ *left = sbit->left;
+ *top = sbit->top;
+ *x_advance = sbit->xadvance;
+ *y_advance = sbit->yadvance;
+
+ goto Exit;
+ }
+ }
+
+ /* otherwise, use an image cache to store glyph outlines, and render */
+ /* them on demand. we can thus support very large sizes easily.. */
+ {
+ FT_Glyph glyf;
+
+ error = FTC_ImageCache_Lookup( handle->image_cache,
+ &handle->image_type,
+ Index,
+ &glyf,
+ NULL );
+
+ if ( !error )
+ error = FTDemo_Glyph_To_Bitmap( handle, glyf, target, left, top,
+ x_advance, y_advance, aglyf );
+ }
+
+ Exit:
+
+#ifdef FT_RGB_FILTER_H
+ /* note that we apply the RGB filter to each cached glyph, which is
+ * a performance killer, but that's better than modifying the cache
+ * at the moment
+ */
+ if ( !error )
+ {
+ if ( target->mode == gr_pixel_mode_lcd ||
+ target->mode == gr_pixel_mode_lcdv )
+ {
+ /* copy the bitmap before filtering it, we don't want to touch
+ * the content of cache nodes at all
+ */
+ {
+ }
+ }
+ }
+
+#endif /* FT_RGB_FILTER_H */
+
+ /* don't accept a `missing' character with zero or negative width */
+ if ( Index == 0 && *x_advance <= 0 )
+ *x_advance = 1;
+
+ return error;
+ }
+
+
+ FT_Error
+ FTDemo_Draw_Index( FTDemo_Handle* handle,
+ grBitmap* bitmap,
+ int gindex,
+ int* pen_x,
+ int* pen_y )
+ {
+ int left, top, x_advance, y_advance;
+ grBitmap bit3;
+ FT_Glyph glyf;
+
+ grColor c;
+ memset(&c, 0, sizeof(grColor));
+
+ error = FTDemo_Index_To_Bitmap(handle, gindex, &bit3, &left, &top,
+ &x_advance, &y_advance, &glyf);
+ if(error)
+ return error;
+
+ /* now render the bitmap into the display surface */
+ grBlitGlyphToBitmap( bitmap, &bit3, *pen_x + left,
+ *pen_y - top, c );
+
+ if ( glyf )
+ FT_Done_Glyph( glyf );
+
+ *pen_x += x_advance + 1;
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_Error
+ FTDemo_Draw_Glyph( FTDemo_Handle* handle,
+ FTDemo_Display* display,
+ FT_Glyph glyph,
+ int* pen_x,
+ int* pen_y )
+ {
+ int left, top, x_advance, y_advance;
+ grBitmap bit3;
+ FT_Glyph glyf;
+
+
+ error = FTDemo_Glyph_To_Bitmap( handle, glyph, &bit3, &left, &top,
+ &x_advance, &y_advance, &glyf );
+ if ( error )
+ {
+ FT_Done_Glyph( glyph );
+
+ return error;
+ }
+
+ /* now render the bitmap into the display surface */
+ grBlitGlyphToBitmap( display->bitmap, &bit3, *pen_x + left,
+ *pen_y - top, display->fore_color );
+
+ if ( glyf )
+ FT_Done_Glyph( glyf );
+
+ *pen_x += x_advance + 1;
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_Error
+ FTDemo_Draw_Slot( FTDemo_Handle* handle,
+ FTDemo_Display* display,
+ FT_GlyphSlot slot,
+ int* pen_x,
+ int* pen_y )
+ {
+ FT_Glyph glyph;
+
+
+ error = FT_Get_Glyph( slot, &glyph );
+ if ( error )
+ return error;
+
+ error = FTDemo_Draw_Glyph( handle, display, glyph, pen_x, pen_y );
+
+ FT_Done_Glyph( glyph );
+
+ return error;
+ }
+
+
+ void
+ FTDemo_String_Set( FTDemo_Handle* handle,
+ const unsigned char* string )
+ {
+ const unsigned char* p = string;
+ unsigned long codepoint;
+ unsigned char in_code;
+ int expect;
+ PGlyph glyph = handle->string;
+
+
+ handle->string_length = 0;
+ codepoint = expect = 0;
+
+ while ( *p )
+ {
+ in_code = *p++ ;
+
+ if ( in_code >= 0xC0 )
+ {
+ if ( in_code < 0xE0 ) /* U+0080 - U+07FF */
+ {
+ expect = 1;
+ codepoint = in_code & 0x1F;
+ }
+ else if ( in_code < 0xF0 ) /* U+0800 - U+FFFF */
+ {
+ expect = 2;
+ codepoint = in_code & 0x0F;
+ }
+ else if ( in_code < 0xF8 ) /* U+10000 - U+10FFFF */
+ {
+ expect = 3;
+ codepoint = in_code & 0x07;
+ }
+ continue;
+ }
+ else if ( in_code >= 0x80 )
+ {
+ --expect;
+
+ if ( expect >= 0 )
+ {
+ codepoint <<= 6;
+ codepoint += in_code & 0x3F;
+ }
+ if ( expect > 0 )
+ continue;
+
+ expect = 0;
+ }
+ else /* ASCII, U+0000 - U+007F */
+ codepoint = in_code;
+
+ if ( handle->encoding != FT_ENCODING_NONE )
+ glyph->glyph_index = FTDemo_Get_Index( handle, codepoint );
+ else
+ glyph->glyph_index = codepoint;
+
+ glyph++;
+ handle->string_length++;
+
+ if ( handle->string_length >= MAX_GLYPHS )
+ break;
+ }
+
+ handle->string_reload = 1;
+ }
+
+
+ static FT_Error
+ string_load( FTDemo_Handle* handle )
+ {
+ int n;
+ FT_Size size;
+ FT_Face face;
+ FT_Pos prev_rsb_delta = 0;
+
+
+ error = FTDemo_Get_Size( handle, &size );
+ if ( error )
+ return error;
+
+ face = size->face;
+
+ for ( n = 0; n < handle->string_length; n++ )
+ {
+ PGlyph glyph = handle->string + n;
+
+
+ /* clear existing image if there is one */
+ if ( glyph->image )
+ {
+ FT_Done_Glyph( glyph->image );
+ glyph->image = NULL;
+ }
+
+ /* load the glyph and get the image */
+ if ( !FT_Load_Glyph( face, glyph->glyph_index,
+ handle->image_type.flags ) &&
+ !FT_Get_Glyph( face->glyph, &glyph->image ) )
+ {
+ FT_Glyph_Metrics* metrics = &face->glyph->metrics;
+
+
+ /* note that in vertical layout, y-positive goes downwards */
+
+ glyph->vvector.x = metrics->vertBearingX - metrics->horiBearingX;
+ glyph->vvector.y = -metrics->vertBearingY - metrics->horiBearingY;
+
+ glyph->vadvance.x = 0;
+ glyph->vadvance.y = -metrics->vertAdvance;
+
+ if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 )
+ glyph->delta = -1 << 6;
+ else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 )
+ glyph->delta = 1 << 6;
+ else
+ glyph->delta = 0;
+ }
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_Error
+ string_render_prepare( FTDemo_Handle* handle,
+ FTDemo_String_Context* sc,
+ FT_Vector* advances )
+ {
+ FT_Face face;
+ FT_Size size;
+ PGlyph glyph;
+ FT_Pos track_kern = 0;
+ FT_UInt prev_index = 0;
+ FT_Vector* prev_advance = NULL;
+ FT_Vector extent = {0, 0};
+ FT_Int i;
+
+
+ error = FTDemo_Get_Size( handle, &size );
+ if ( error )
+ return error;
+
+ face = size->face;
+
+ if ( !sc->vertical && sc->kerning_degree )
+ {
+ FT_Fixed ptsize;
+
+
+ ptsize = FT_MulFix( face->units_per_EM, face->size->metrics.x_scale );
+
+ if ( FT_Get_Track_Kerning( face, ptsize << 10,
+ -sc->kerning_degree,
+ &track_kern ) )
+ track_kern = 0;
+ else
+ track_kern >>= 10;
+ }
+
+ for ( i = 0; i < handle->string_length; i++ )
+ {
+ glyph = handle->string + i;
+
+ if ( !glyph->image )
+ continue;
+
+ if ( sc->vertical )
+ advances[i] = glyph->vadvance;
+ else
+ {
+ advances[i] = glyph->image->advance;
+ advances[i].x >>= 10;
+ advances[i].y >>= 10;
+
+ if ( prev_advance )
+ {
+ prev_advance->x += track_kern;
+
+ if ( sc->kerning_mode )
+ {
+ FT_Vector kern;
+
+
+ FT_Get_Kerning( face, prev_index, glyph->glyph_index,
+ FT_KERNING_UNFITTED, &kern );
+
+ prev_advance->x += kern.x;
+ prev_advance->y += kern.y;
+
+ if ( sc->kerning_mode > KERNING_MODE_NORMAL )
+ prev_advance->x += glyph->delta;
+ }
+ }
+ }
+
+ if ( prev_advance )
+ {
+ if ( handle->hinted )
+ {
+ prev_advance->x = ROUND( prev_advance->x );
+ prev_advance->y = ROUND( prev_advance->y );
+ }
+
+ extent.x += prev_advance->x;
+ extent.y += prev_advance->y;
+ }
+
+ prev_index = glyph->glyph_index;
+ prev_advance = advances + i;
+ }
+
+ if ( prev_advance )
+ {
+ if ( handle->hinted )
+ {
+ prev_advance->x = ROUND( prev_advance->x );
+ prev_advance->y = ROUND( prev_advance->y );
+ }
+
+ extent.x += prev_advance->x;
+ extent.y += prev_advance->y;
+
+ /*store the extent in the last slot */
+ i = handle->string_length - 1;
+ advances[i] = extent;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ static void
+ gamma_ramp_apply( FT_Byte gamma_ramp[256],
+ grBitmap* bitmap )
+ {
+ int i, j;
+ FT_Byte* p = (FT_Byte*)bitmap->buffer;
+
+ if ( bitmap->pitch < 0 )
+ p += -bitmap->pitch * ( bitmap->rows - 1 );
+
+ for ( i = 0; i < bitmap->rows; i++ )
+ {
+ for ( j = 0; j < bitmap->width; j++ )
+ p[j] = gamma_ramp[p[j]];
+
+ p += bitmap->pitch;
+ }
+ }
+
+
+ FT_Error
+ FTDemo_String_Draw( FTDemo_Handle* handle,
+ FTDemo_Display* display,
+ FTDemo_String_Context* sc,
+ int x,
+ int y )
+ {
+ int n;
+ FT_Vector pen, advances[MAX_GLYPHS];
+ FT_Size size;
+ FT_Face face;
+
+
+ if ( !sc ||
+ x < 0 ||
+ y < 0 ||
+ x > display->bitmap->width ||
+ y > display->bitmap->rows )
+ return FT_Err_Invalid_Argument;
+
+ error = FTDemo_Get_Size( handle, &size );
+ if ( error )
+ return error;
+
+ face = size->face;
+
+ if ( handle->string_reload )
+ {
+ error = string_load( handle );
+ if ( error )
+ return error;
+
+ handle->string_reload = 0;
+ }
+
+ error = string_render_prepare( handle, sc, advances );
+ if ( error )
+ return error;
+
+ /* change to Cartesian coordinates */
+ y = display->bitmap->rows - y;
+
+ /* get the extent, which we store in the last slot */
+ pen = advances[handle->string_length - 1];
+
+ pen.x = FT_MulFix( pen.x, sc->center );
+ pen.y = FT_MulFix( pen.y, sc->center );
+
+ /* XXX sbits */
+ /* get pen position */
+ if ( sc->matrix && FT_IS_SCALABLE( face ) )
+ {
+ FT_Vector_Transform( &pen, sc->matrix );
+ pen.x = ( x << 6 ) - pen.x;
+ pen.y = ( y << 6 ) - pen.y;
+ }
+ else
+ {
+ pen.x = ROUND( ( x << 6 ) - pen.x );
+ pen.y = ROUND( ( y << 6 ) - pen.y );
+ }
+
+ for ( n = 0; n < handle->string_length; n++ )
+ {
+ PGlyph glyph = handle->string + n;
+ FT_Glyph image;
+ FT_BBox bbox;
+
+
+ if ( !glyph->image )
+ continue;
+
+ /* copy image */
+ error = FT_Glyph_Copy( glyph->image, &image );
+ if ( error )
+ continue;
+
+ if ( image->format != FT_GLYPH_FORMAT_BITMAP )
+ {
+ if ( sc->vertical )
+ error = FT_Glyph_Transform( image, NULL, &glyph->vvector );
+
+ if ( !error )
+ error = FT_Glyph_Transform( image, sc->matrix, &pen );
+
+ if ( error )
+ {
+ FT_Done_Glyph( image );
+ continue;
+ }
+ }
+ else
+ {
+ FT_BitmapGlyph bitmap = (FT_BitmapGlyph)image;
+
+
+ if ( sc->vertical )
+ {
+ bitmap->left += ( glyph->vvector.x + pen.x ) >> 6;
+ bitmap->top += ( glyph->vvector.x + pen.y ) >> 6;
+ }
+ else
+ {
+ bitmap->left += pen.x >> 6;
+ bitmap->top += pen.y >> 6;
+ }
+ }
+
+ if ( sc->matrix )
+ FT_Vector_Transform( advances + n, sc->matrix );
+
+ pen.x += advances[n].x;
+ pen.y += advances[n].y;
+
+ FT_Glyph_Get_CBox( image, FT_GLYPH_BBOX_PIXELS, &bbox );
+
+#if 0
+ if ( n == 0 )
+ {
+ fprintf( stderr, "bbox = [%ld %ld %ld %ld]\n",
+ bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax );
+ }
+#endif
+
+ /* check bounding box; if it is completely outside the */
+ /* display surface, we don't need to render it */
+ if ( bbox.xMax > 0 &&
+ bbox.yMax > 0 &&
+ bbox.xMin < display->bitmap->width &&
+ bbox.yMin < display->bitmap->rows )
+ {
+ int left, top, dummy1, dummy2;
+ grBitmap bit3;
+ FT_Glyph glyf;
+
+
+ error = FTDemo_Glyph_To_Bitmap( handle, image, &bit3, &left, &top,
+ &dummy1, &dummy2, &glyf );
+ if ( !error )
+ {
+ if ( sc->gamma_ramp )
+ gamma_ramp_apply( sc->gamma_ramp, &bit3 );
+
+ /* change back to the usual coordinates */
+ top = display->bitmap->rows - top;
+
+ /* now render the bitmap into the display surface */
+ grBlitGlyphToBitmap( display->bitmap, &bit3, left, top,
+ display->fore_color );
+
+ if ( glyf )
+ FT_Done_Glyph( glyf );
+ }
+ }
+
+ FT_Done_Glyph( image );
+ }
+
+ return error;
+ }
+
+
+ FT_Encoding
+ FTDemo_Make_Encoding_Tag( const char* s )
+ {
+ int i;
+ unsigned long l = 0;
+
+
+ for ( i = 0; i < 4; i++ )
+ {
+ if ( !s[i] )
+ break;
+ l <<= 8;
+ l += (unsigned long)s[i];
+ }
+
+ return (FT_Encoding)l;
+ }
+
+
+/* End */
diff --git a/kernel/kls_ttf/ftcommon.h b/kernel/kls_ttf/ftcommon.h
new file mode 100644
index 0000000..304527f
--- /dev/null
+++ b/kernel/kls_ttf/ftcommon.h
@@ -0,0 +1,307 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 2005, 2006 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* */
+/* ftcommon.h - common routines for the FreeType demo programs. */
+/* */
+/****************************************************************************/
+
+#ifndef _FT_COMMON_H_
+#define _FT_COMMON_H_
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include FT_CACHE_H
+#include FT_CACHE_MANAGER_H
+
+#include FT_GLYPH_H
+#include FT_BITMAP_H
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+ extern FT_Error error;
+
+ /* forward declarations */
+ extern void PanicZ( const char* message );
+
+#undef NODEBUG
+
+#define LOG( x ) /* */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** DISPLAY-SPECIFIC DEFINITIONS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+#include "graph.h"
+#include "grobjs.h"
+#include "grfont.h"
+
+ typedef struct
+ {
+ grSurface* surface;
+ grBitmap* bitmap;
+ grColor fore_color;
+ grColor back_color;
+
+ } FTDemo_Display;
+
+ grBitmap*
+ FTDemo_Display_New(void);
+
+
+ void
+ FTDemo_Display_Done(grBitmap *);
+
+
+ /* fill the bitmap with background color */
+ void
+ FTDemo_Display_Clear(grBitmap *);
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** FREETYPE-SPECIFIC DEFINITIONS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#define MAX_GLYPHS 512 /* at most 512 glyphs in the string */
+#define MAX_GLYPH_BYTES 150000 /* 150kB for the glyph image cache */
+
+
+ typedef struct TGlyph_
+ {
+ FT_UInt glyph_index;
+ FT_Glyph image; /* the glyph image */
+
+ FT_Pos delta; /* delta caused by hinting */
+ FT_Vector vvector; /* vert. origin => hori. origin */
+ FT_Vector vadvance; /* vertical advance */
+
+ } TGlyph, *PGlyph;
+
+ /* this simple record is used to model a given `installed' face */
+ typedef struct TFont_
+ {
+ const char* filepathname;
+ int face_index;
+ int cmap_index;
+ int num_indices;
+ void* file_address; /* for preloaded files */
+ size_t file_size;
+
+ } TFont, *PFont;
+
+ enum {
+ LCD_MODE_AA = 0,
+ LCD_MODE_LIGHT,
+ LCD_MODE_RGB,
+ LCD_MODE_BGR,
+ LCD_MODE_VRGB,
+ LCD_MODE_VBGR,
+ N_LCD_MODES
+ };
+
+ enum {
+ KERNING_DEGREE_NONE = 0,
+ KERNING_DEGREE_LIGHT,
+ KERNING_DEGREE_MEDIUM,
+ KERNING_DEGREE_TIGHT,
+ N_KERNING_DEGREES,
+ };
+
+ enum {
+ KERNING_MODE_NONE = 0, /* 0: no kerning; */
+ KERNING_MODE_NORMAL, /* 1: `kern' values */
+ KERNING_MODE_SMART, /* 2: `kern' + side bearing errors */
+ N_KERNING_MODES
+ };
+
+ typedef struct
+ {
+ int kerning_mode;
+ int kerning_degree;
+ FT_Fixed center; /* 0..1 */
+ int vertical; /* displayed vertically? */
+ FT_Matrix* matrix; /* string transformation */
+ FT_Byte* gamma_ramp; /* an array of size 256 */
+
+ } FTDemo_String_Context;
+
+ typedef struct
+ {
+ FT_Library library; /* the FreeType library */
+ FTC_Manager cache_manager; /* the cache manager */
+ FTC_ImageCache image_cache; /* the glyph image cache */
+ FTC_SBitCache sbits_cache; /* the glyph small bitmaps cache */
+ FTC_CMapCache cmap_cache; /* the charmap cache.. */
+
+ PFont* fonts; /* installed fonts */
+ int num_fonts;
+ int max_fonts;
+
+ int use_sbits_cache; /* toggle sbits cache */
+
+ /* use FTDemo_Set_Current_XXX to set the following two fields */
+ PFont current_font; /* selected font */
+ FTC_ImageTypeRec image_type;
+
+ /* call FTDemo_Update_Current_Flags after setting any of the following fields */
+ int hinted; /* is glyph hinting active? */
+ int antialias; /* is anti-aliasing active? */
+ int use_sbits; /* do we use embedded bitmaps? */
+ int low_prec; /* force low precision */
+ int autohint; /* force auto-hinting */
+ int lcd_mode;
+ int preload; /* force font file preloading */
+
+ /* don't touch the following fields! */
+
+ /* used for string rendering */
+ TGlyph string[MAX_GLYPHS];
+ int string_length;
+ int string_reload;
+
+ FT_Encoding encoding;
+ FT_Bitmap bitmap; /* used as bitmap conversion buffer */
+
+ } FTDemo_Handle;
+
+
+ FTDemo_Handle*
+ FTDemo_New( FT_Encoding encoding );
+
+
+ void
+ FTDemo_Done( FTDemo_Handle* handle );
+
+
+ /* install a font */
+ FT_Error
+ FTDemo_Install_Font( FTDemo_Handle* handle,
+ const char* filepath );
+
+
+ void
+ FTDemo_Set_Preload( FTDemo_Handle* handle,
+ int preload );
+
+ void
+ FTDemo_Set_Current_Font( FTDemo_Handle* handle,
+ PFont font );
+
+ void
+ FTDemo_Set_Current_Size( FTDemo_Handle* handle,
+ int pixel_size );
+
+ void
+ FTDemo_Set_Current_Pointsize( FTDemo_Handle* handle,
+ int point_size,
+ int res );
+
+ void
+ FTDemo_Update_Current_Flags( FTDemo_Handle* handle );
+
+
+ /* charcode => glyph index of current font */
+ FT_UInt
+ FTDemo_Get_Index( FTDemo_Handle* handle,
+ FT_UInt32 charcode );
+
+
+ /* get FT_Size of current font */
+ FT_Error
+ FTDemo_Get_Size( FTDemo_Handle* handle,
+ FT_Size* asize );
+
+
+ /* convert a FT_Glyph to a grBitmap (don't free target->buffer) */
+ /* if aglyf != NULL, you should FT_Glyph_Done the aglyf */
+ FT_Error
+ FTDemo_Glyph_To_Bitmap( FTDemo_Handle* handle,
+ FT_Glyph glyf,
+ grBitmap* target,
+ int* left,
+ int* top,
+ int* x_advance,
+ int* y_advance,
+ FT_Glyph* aglyf );
+
+ /* get a grBitmap from glyph index (don't free target->buffer) */
+ /* if aglyf != NULL, you should FT_Glyph_Done the aglyf */
+ FT_Error
+ FTDemo_Index_To_Bitmap( FTDemo_Handle* handle,
+ FT_ULong Index,
+ grBitmap* target,
+ int* left,
+ int* top,
+ int* x_advance,
+ int* y_advance,
+ FT_Glyph* aglyf );
+
+
+ /* given glyph index, draw a glyph on the display */
+ FT_Error
+ FTDemo_Draw_Index( FTDemo_Handle* handle,
+ grBitmap* display,
+ int gindex,
+ int* pen_x,
+ int* pen_y);
+
+
+ /* given FT_Glyph, draw a glyph on the display */
+ FT_Error
+ FTDemo_Draw_Glyph( FTDemo_Handle* handle,
+ FTDemo_Display* display,
+ FT_Glyph glyph,
+ int* pen_x,
+ int* pen_y);
+
+
+ /* given FT_GlyphSlot, draw a glyph on the display */
+ FT_Error
+ FTDemo_Draw_Slot( FTDemo_Handle* handle,
+ FTDemo_Display* display,
+ FT_GlyphSlot slot,
+ int* pen_x,
+ int* pen_y);
+
+
+ /* set the string to be drawn */
+ void
+ FTDemo_String_Set( FTDemo_Handle* handle,
+ const unsigned char* string );
+
+
+ /* draw a string centered at (center_x, center_y) -- */
+ /* note that handle->use_sbits_cache is not supported */
+ FT_Error
+ FTDemo_String_Draw( FTDemo_Handle* handle,
+ FTDemo_Display* display,
+ FTDemo_String_Context* sc,
+ int center_x,
+ int center_y );
+
+
+ /* make a FT_Encoding tag from a string */
+ FT_Encoding
+ FTDemo_Make_Encoding_Tag( const char* s );
+
+
+#endif /* _FTCOMMON_H_ */
+
+/* End */
diff --git a/kernel/kls_ttf/ftview/Makefile.am b/kernel/kls_ttf/ftview/Makefile.am
new file mode 100644
index 0000000..d744d11
--- /dev/null
+++ b/kernel/kls_ttf/ftview/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I. @SQ_FT_CFLAGS@
+
+noinst_LTLIBRARIES = libftview.la
+
+libftview_la_SOURCES = gblblit.cpp gblender.cpp grblit.cpp grfont.cpp grobjs.cpp
+
+EXTRA_DIST = gblblit.h gblender.h gblvbgr.h grblit.cpp grevents.h grobjs.cpp \
+gblany.h gblcolor.h gblhbgr.h gblvrgb.h grblit.h grfont.cpp grobjs.h README \
+gblblit.cpp gblender.cpp gblhrgb.h graph.h grconfig.h grfont.h grtypes.h
diff --git a/kernel/kls_ttf/ftview/README b/kernel/kls_ttf/ftview/README
new file mode 100644
index 0000000..61dba91
--- /dev/null
+++ b/kernel/kls_ttf/ftview/README
@@ -0,0 +1 @@
+All code in this directory is taken from ftdemos-2.1.10 \ No newline at end of file
diff --git a/kernel/kls_ttf/ftview/gblany.h b/kernel/kls_ttf/ftview/gblany.h
new file mode 100644
index 0000000..a0bc750
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblany.h
@@ -0,0 +1,133 @@
+/* check that all macros are correctly set
+ */
+#ifndef GDST_INCR
+#error "GDST_INCR not defined"
+#endif
+
+#ifndef GDST_TYPE
+#error "GDST_TYPE not defined"
+#endif
+
+#ifndef GDST_READ
+#error "GDST_READ not defined"
+#endif
+
+#ifdef GBLENDER_STORE_BYTES
+# ifndef GDST_STOREB
+# error "GDST_STOREB not defined"
+# endif
+#else
+# ifndef GDST_STOREP
+# error "GDST_STOREP not defined"
+# endif
+#endif /* !STORE_BYTES */
+
+#ifndef GDST_STOREC
+#error "GDST_STOREC not defined"
+#endif
+
+#ifndef GDST_COPY
+#error "GDST_COPY not defined"
+#endif
+
+#ifndef GDST_COPY_VAR
+#error "GDST_COPY_VAR not defined"
+#endif
+
+#undef GCONCAT
+#undef GCONCATX
+#define GCONCAT(x,y) GCONCATX(x,y)
+#define GCONCATX(x,y) x ## y
+
+
+#include <stdio.h>
+
+static void
+GCONCAT( _gblender_blit_gray8_, GDST_TYPE )( GBlenderBlit blit,
+ GBlenderPixel color )
+{
+
+ GBlender blender = blit->blender;
+ int r = (color >> 16) & 255;
+ int g = (color >> 8) & 255;
+ int b = (color) & 255;
+
+ GDST_COPY_VAR
+
+#include "gblcolor.h"
+
+}
+
+
+static void
+GCONCAT( _gblender_blit_hrgb_, GDST_TYPE )( GBlenderBlit blit,
+ GBlenderPixel color )
+{
+ GBlender blender = blit->blender;
+ int r = (color >> 16) & 255;
+ int g = (color >> 8) & 255;
+ int b = (color) & 255;
+
+ GDST_COPY_VAR
+
+#include "gblhrgb.h"
+}
+
+
+static void
+GCONCAT( _gblender_blit_hbgr_, GDST_TYPE )( GBlenderBlit blit,
+ GBlenderPixel color )
+{
+ GBlender blender = blit->blender;
+ int r = (color >> 16) & 255;
+ int g = (color >> 8) & 255;
+ int b = (color) & 255;
+
+ GDST_COPY_VAR
+
+#include "gblhbgr.h"
+}
+
+
+static void
+GCONCAT( _gblender_blit_vrgb_, GDST_TYPE )( GBlenderBlit blit,
+ GBlenderPixel color )
+{
+ GBlender blender = blit->blender;
+ int r = (color >> 16) & 255;
+ int g = (color >> 8) & 255;
+ int b = (color) & 255;
+
+ GDST_COPY_VAR
+
+#include "gblvrgb.h"
+}
+
+static void
+GCONCAT( _gblender_blit_vbgr_, GDST_TYPE )( GBlenderBlit blit,
+ GBlenderPixel color )
+{
+ GBlender blender = blit->blender;
+ int r = (color >> 16) & 255;
+ int g = (color >> 8) & 255;
+ int b = (color) & 255;
+
+ GDST_COPY_VAR
+
+#include "gblvbgr.h"
+}
+
+/* unset the macros, to prevent accidental re-use
+ */
+
+#undef GCONCATX
+#undef GCONCAT
+#undef GDST_TYPE
+#undef GDST_INCR
+#undef GDST_READ
+#undef GDST_COPY
+#undef GDST_STOREB
+#undef GDST_STOREP
+#undef GDST_STOREC
+#undef GDST_COPY_VAR
+/* EOF */
diff --git a/kernel/kls_ttf/ftview/gblblit.cpp b/kernel/kls_ttf/ftview/gblblit.cpp
new file mode 100644
index 0000000..afb363d
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblblit.cpp
@@ -0,0 +1,318 @@
+#include "gblblit.h"
+
+#include <stdio.h>
+
+/* blitting gray glyphs
+ */
+
+/* generic macros
+ */
+#define GRGB_PACK(r,g,b) ( ((GBlenderPixel)(r) << 16) | \
+ ((GBlenderPixel)(g) << 8) | \
+ (GBlenderPixel)(b) )
+
+#define GDST_STORE3(d,r,g,b) (d)[0] = (unsigned char)(r); \
+ (d)[1] = (unsigned char)(g); \
+ (d)[2] = (unsigned char)(b)
+
+/* */
+
+#define GRGB_TO_RGB565(r,g,b) ((unsigned short)( ((r << 8) & 0xF800) | \
+ ((g << 3) & 0x07E0) | \
+ ((b >> 3) & 0x001F) ) )
+
+#define GRGB565_TO_RGB24(p) ( ( ((p) << 8) & 0xF80000 ) | \
+ ( ((p) << 3) & 0x0700F8 ) | \
+ ( ((p) << 5) & 0x00FC00 ) | \
+ ( ((p) >> 1) & 0x000300 ) | \
+ ( ((p) >> 2) & 0x000007 ) )
+
+#define GRGB24_TO_RGB565(p) ( (unsigned short)( (((p) >> 8) & 0xF800 ) | \
+ (((p) >> 5) & 0x07E0 ) | \
+ (((p) >> 3) & 0x001F ) ) )
+
+/* */
+
+#define GRGB_TO_BGR565(r,g,b) GRGB_TO_RGB565(b,g,r)
+
+#define GBGR565_TO_RGB24(p) ( ( ((p) << 19) & 0xF80000 ) | \
+ ( ((p) << 12) & 0x070000 ) | \
+ ( ((p) << 5) & 0x00FC00 ) | \
+ ( ((p) >> 1) & 0x000300 ) | \
+ ( ((p) >> 8) & 0x0000F8 ) | \
+ ( ((p) >> 13) & 0x000007 ) )
+
+#define GRGB24_TO_BGR565(p) ( (unsigned short)( (((p) << 8) & 0xF800 ) | \
+ (((p) >> 5) & 0x07E0 ) | \
+ (((p) >> 19) & 0x001F ) ) )
+
+/* */
+
+/* Rgb32 blitting routines
+ */
+
+#define GDST_TYPE rgb32
+#define GDST_INCR 4
+#define GDST_READ(d,p) (p) = *(GBlenderPixel*)(d) & 0xFFFFFF
+#define GDST_COPY(d) *(GBlenderPixel*)(d) = color
+#define GDST_STOREP(d,cells,a) *(GBlenderPixel*)(d) = (cells)[(a)]
+#define GDST_STOREB(d,cells,a) \
+ { \
+ GBlenderCell* _g = (cells) + (a)*3; \
+ \
+ GDST_STOREC(d,_g[0],_g[1],_g[2]); \
+ }
+#define GDST_STOREC(d,r,g,b) *(GBlenderPixel*)(d) = GRGB_PACK(r,g,b)
+#define GDST_COPY_VAR /* nothing */
+
+#include "gblany.h"
+
+/* Rgb24 blitting routines
+ */
+
+#define GDST_TYPE rgb24
+#define GDST_INCR 3
+#define GDST_READ(d,p) (p) = GRGB_PACK((d)[0],(d)[1],(d)[2])
+#define GDST_COPY(d) GDST_STORE3(d,r,g,b)
+#define GDST_STOREC(d,r,g,b) GDST_STORE3(d,r,g,b)
+
+#define GDST_STOREB(d,cells,a) \
+ { \
+ GBlenderCell* _g = (cells) + (a)*3; \
+ \
+ (d)[0] = _g[0]; \
+ (d)[1] = _g[1]; \
+ (d)[2] = _g[2]; \
+ }
+
+#define GDST_STOREP(d,cells,a) \
+ { \
+ GBlenderPixel _pix = (cells)[(a)]; \
+ \
+ GDST_STORE3(d,_pix >> 16,_pix >> 8,_pix); \
+ }
+
+#define GDST_COPY_VAR /* nothing */
+
+#include "gblany.h"
+
+/* Rgb565 blitting routines
+ */
+
+#define GDST_TYPE rgb565
+#define GDST_INCR 2
+
+#define GDST_READ(d,p) p = (GBlenderPixel)*(unsigned short*)(d); \
+ p = GRGB565_TO_RGB24(p)
+
+#define GDST_COPY_VAR unsigned short pix = GRGB_TO_RGB565(r,g,b);
+#define GDST_COPY(d) *(unsigned short*)(d) = pix
+
+#define GDST_STOREB(d,cells,a) \
+ { \
+ GBlenderCell* _g = (cells) + (a)*3; \
+ \
+ *(unsigned short*)(d) = GRGB_TO_RGB565(_g[0],_g[1],_g[2]); \
+ }
+
+#define GDST_STOREP(d,cells,a) \
+ { \
+ GBlenderPixel _pix = (cells)[(a)]; \
+ \
+ *(unsigned short*)(d) = GRGB24_TO_RGB565(_pix); \
+ }
+
+#define GDST_STOREC(d,r,g,b) *(unsigned short*)(d) = GRGB_TO_RGB565(r,g,b)
+
+#include "gblany.h"
+
+/* Bgr565 blitting routines
+ */
+#define GDST_TYPE bgr565
+#define GDST_INCR 2
+
+#define GDST_READ(d,p) p = (GBlenderPixel)*(unsigned short*)(d); \
+ p = GBGR565_TO_RGB24(p)
+
+#define GDST_COPY_VAR unsigned short pix = GRGB_TO_BGR565(r,g,b);
+#define GDST_COPY(d) *(d) = pix
+
+#define GDST_STOREB(d,cells,a) \
+ { \
+ GBlenderCell* _g = (cells) + (a)*3; \
+ \
+ *(unsigned short*)(d) = GRGB_TO_BGR565(_g[0],_g[1],_g[2]); \
+ }
+
+#define GDST_STOREP(d,cells,a) \
+ { \
+ GBlenderPixel _pix = (cells)[(a)]; \
+ \
+ *(unsigned short*)(d) = GRGB24_TO_BGR565(_pix); \
+ }
+
+#define GDST_STOREC(d,r,g,b) *(unsigned short*)(d) = GRGB_TO_BGR565(r,g,b)
+
+#include "gblany.h"
+
+/* */
+
+static void
+_gblender_blit_dummy( GBlenderBlit blit,
+ GBlenderPixel color )
+{
+ (blit)=(blit);
+ (color)=(color);
+}
+
+
+GBLENDER_APIDEF( int )
+gblender_blit_init( GBlenderBlit blit,
+ GBlender blender,
+ int dst_x,
+ int dst_y,
+ GBlenderSourceFormat src_format,
+ const unsigned char* src_buffer,
+ int src_pitch,
+ int src_width,
+ int src_height,
+ GBlenderTargetFormat dst_format,
+ unsigned char* dst_buffer,
+ int dst_pitch,
+ int dst_width,
+ int dst_height )
+{
+ int src_x = 0;
+ int src_y = 0;
+ int delta;
+ GBlenderBlitFunc blit_func = 0;
+
+ switch ( src_format )
+ {
+ case GBLENDER_SOURCE_GRAY8:
+ switch ( dst_format )
+ {
+ case GBLENDER_TARGET_RGB32: blit_func = _gblender_blit_gray8_rgb32; break;
+ case GBLENDER_TARGET_RGB24: blit_func = _gblender_blit_gray8_rgb24; break;
+ case GBLENDER_TARGET_RGB565: blit_func = _gblender_blit_gray8_rgb565; break;
+ case GBLENDER_TARGET_BGR565: blit_func = _gblender_blit_gray8_bgr565; break;
+ default:
+ ;
+ }
+ break;
+
+ case GBLENDER_SOURCE_HRGB:
+ switch ( dst_format )
+ {
+ case GBLENDER_TARGET_RGB32: blit_func = _gblender_blit_hrgb_rgb32; break;
+ case GBLENDER_TARGET_RGB24: blit_func = _gblender_blit_hrgb_rgb24; break;
+ case GBLENDER_TARGET_RGB565: blit_func = _gblender_blit_hrgb_rgb565; break;
+ case GBLENDER_TARGET_BGR565: blit_func = _gblender_blit_hrgb_bgr565; break;
+ default:
+ ;
+ }
+ break;
+
+ case GBLENDER_SOURCE_HBGR:
+ switch ( dst_format )
+ {
+ case GBLENDER_TARGET_RGB32: blit_func = _gblender_blit_hbgr_rgb32; break;
+ case GBLENDER_TARGET_RGB24: blit_func = _gblender_blit_hbgr_rgb24; break;
+ case GBLENDER_TARGET_RGB565: blit_func = _gblender_blit_hbgr_rgb565; break;
+ case GBLENDER_TARGET_BGR565: blit_func = _gblender_blit_hbgr_bgr565; break;
+ default:
+ ;
+ }
+ break;
+
+ case GBLENDER_SOURCE_VRGB:
+ switch ( dst_format )
+ {
+ case GBLENDER_TARGET_RGB32: blit_func = _gblender_blit_vrgb_rgb32; break;
+ case GBLENDER_TARGET_RGB24: blit_func = _gblender_blit_vrgb_rgb24; break;
+ case GBLENDER_TARGET_RGB565: blit_func = _gblender_blit_vrgb_rgb565; break;
+ case GBLENDER_TARGET_BGR565: blit_func = _gblender_blit_vrgb_bgr565; break;
+ default:
+ ;
+ }
+ break;
+
+ case GBLENDER_SOURCE_VBGR:
+ switch ( dst_format )
+ {
+ case GBLENDER_TARGET_RGB32: blit_func = _gblender_blit_vbgr_rgb32; break;
+ case GBLENDER_TARGET_RGB24: blit_func = _gblender_blit_vbgr_rgb24; break;
+ case GBLENDER_TARGET_RGB565: blit_func = _gblender_blit_vbgr_rgb565; break;
+ case GBLENDER_TARGET_BGR565: blit_func = _gblender_blit_vbgr_bgr565; break;
+ default:
+ ;
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ blit->blender = blender;
+ blit->blit_func = blit_func;
+
+ if ( blit_func == 0 )
+ {
+ /* unsupported blit mode
+ */
+ blit->blit_func = _gblender_blit_dummy;
+ return -2;
+ }
+
+ if ( dst_x < 0 )
+ {
+ src_width += dst_x;
+ src_x -= dst_x;
+ dst_x = 0;
+ }
+
+ delta = dst_x + src_width - dst_width;
+ if ( delta > 0 )
+ src_width -= delta;
+
+ if ( dst_y < 0 )
+ {
+ src_height += dst_y;
+ src_y -= dst_y;
+ dst_y = 0;
+ }
+
+ delta = dst_y + src_height - dst_height;
+ if ( delta > 0 )
+ src_height -= delta;
+
+ /* nothing to blit
+ */
+ if ( src_width <= 0 || src_height <= 0 )
+ {
+ blit->blit_func = _gblender_blit_dummy;
+ return -1;
+ }
+
+ blit->width = src_width;
+ blit->height = src_height;
+ blit->src_format = src_format;
+ blit->dst_format = dst_format;
+
+ blit->src_x = src_x;
+ blit->src_y = src_y;
+ blit->src_line = src_buffer + src_pitch*src_y;
+ blit->src_pitch = src_pitch;
+ if ( src_pitch < 0 )
+ blit->src_line -= (src_height-1)*src_pitch;
+
+ blit->dst_x = dst_x;
+ blit->dst_y = dst_y;
+ blit->dst_line = dst_buffer + dst_pitch*dst_y;
+ blit->dst_pitch = dst_pitch;
+ if ( dst_pitch < 0 )
+ blit->dst_line -= (dst_height-1)*dst_pitch;
+
+ return 0;
+}
+
diff --git a/kernel/kls_ttf/ftview/gblblit.h b/kernel/kls_ttf/ftview/gblblit.h
new file mode 100644
index 0000000..564a21d
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblblit.h
@@ -0,0 +1,82 @@
+#ifndef __GBLENDER_BLIT_H__
+#define __GBLENDER_BLIT_H__
+
+#include "gblender.h"
+
+/*
+ * blitting interface
+ *
+ */
+
+typedef enum
+{
+ GBLENDER_SOURCE_GRAY8 = 0,
+ GBLENDER_SOURCE_HRGB,
+ GBLENDER_SOURCE_HBGR,
+ GBLENDER_SOURCE_VRGB,
+ GBLENDER_SOURCE_VBGR,
+
+ GBLENDER_SOURCE_MAX
+
+} GBlenderSourceFormat;
+
+
+typedef enum
+{
+ GBLENDER_TARGET_GRAY8 = 0,
+ GBLENDER_TARGET_RGB32,
+ GBLENDER_TARGET_RGB24,
+ GBLENDER_TARGET_RGB565,
+ GBLENDER_TARGET_BGR565,
+
+ GBLENDER_TARGET_MAX
+
+} GBlenderTargetFormat;
+
+typedef struct GBlenderBlitRec_* GBlenderBlit;
+
+typedef void (*GBlenderBlitFunc)( GBlenderBlit blit,
+ GBlenderPixel color );
+
+typedef struct GBlenderBlitRec_
+{
+ int width;
+ int height;
+ const unsigned char* src_line;
+ int src_pitch;
+ int src_x;
+ int src_y;
+ unsigned char* dst_line;
+ int dst_pitch;
+ int dst_x;
+ int dst_y;
+ GBlenderSourceFormat src_format;
+ GBlenderTargetFormat dst_format;
+
+ GBlender blender;
+ GBlenderBlitFunc blit_func;
+
+} GBlenderBlitRec;
+
+
+
+GBLENDER_API( int )
+gblender_blit_init( GBlenderBlit blit,
+ GBlender blender,
+ int dst_x,
+ int dst_y,
+ GBlenderSourceFormat src_format,
+ const unsigned char* src_buffer,
+ int src_pitch,
+ int src_width,
+ int src_height,
+ GBlenderTargetFormat dst_format,
+ unsigned char* dst_buffer,
+ int dst_pitch,
+ int dst_width,
+ int dst_height );
+
+#define gblender_blit_run(b,color) (b)->blit_func( (b), (color) )
+
+
+#endif /* __GBLENDER_BLIT_H__ */
diff --git a/kernel/kls_ttf/ftview/gblcolor.h b/kernel/kls_ttf/ftview/gblcolor.h
new file mode 100644
index 0000000..0aa2b6d
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblcolor.h
@@ -0,0 +1,56 @@
+
+ GBLENDER_VARS(blender,color);
+
+ int h = blit->height;
+ const unsigned char* src_line = blit->src_line;
+ unsigned char* dst_line = blit->dst_line;
+
+ /* make compiler happy */
+ (r)=(r);
+ (g)=(g);
+ (b)=(b);
+
+ do
+ {
+ const unsigned char* src = src_line + (blit->src_x);
+ unsigned char* dst = dst_line + blit->dst_x*GDST_INCR;
+ int w = blit->width;
+
+ do
+ {
+ int a = GBLENDER_SHADE_INDEX(src[0]);
+
+ if ( a == 0 )
+ {
+ /* nothing */
+ }
+ else if ( a == GBLENDER_SHADE_COUNT )
+ {
+ GDST_COPY(dst);
+ }
+ else
+ {
+ GBlenderPixel back;
+
+ GDST_READ(dst,back);
+
+ GBLENDER_LOOKUP( blender, back );
+
+#ifdef GBLENDER_STORE_BYTES
+ GDST_STOREB(dst,_gcells,a);
+#else
+ GDST_STOREP(dst,_gcells,a);
+#endif
+ }
+
+ src += 1;
+ dst += GDST_INCR;
+ }
+ while (--w > 0);
+
+ src_line += blit->src_pitch;
+ dst_line += blit->dst_pitch;
+ }
+ while (--h > 0);
+
+ GBLENDER_CLOSE(blender);
diff --git a/kernel/kls_ttf/ftview/gblender.cpp b/kernel/kls_ttf/ftview/gblender.cpp
new file mode 100644
index 0000000..a0f204d
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblender.cpp
@@ -0,0 +1,381 @@
+#include "gblender.h"
+#include <stdlib.h>
+#include <math.h>
+
+static void
+gblender_set_gamma_table( double gamma_value,
+ unsigned short* gamma_ramp,
+ unsigned char* gamma_ramp_inv )
+{
+ int gmax = (256 << GBLENDER_GAMMA_SHIFT)-1;
+
+ if ( gamma_value <= 0 ) /* special case for sRGB */
+ {
+ int ii;
+
+ for ( ii = 0; ii < 256; ii++ )
+ {
+ double x = (double)ii / 255.0;
+
+ if ( x <= 0.03926 )
+ x = x/12.92;
+ else
+ x = pow( (x+0.055)/ 1.055, 2.4 );
+
+ gamma_ramp[ii] = (unsigned short)(gmax*x);
+ }
+
+ for ( ii = 0; ii < gmax; ii++ )
+ {
+ double x = (double)ii / gmax;
+
+ if ( x <= 0.00304 )
+ x = 12.92*x;
+ else
+ x = 1.055*pow(x,1/2.4) - 0.055;
+
+ gamma_ramp_inv[ii] = (unsigned char)(255*x);
+ }
+ }
+ else
+ {
+ int ii;
+ double gamma_inv = 1.0f / gamma_value;
+
+ /* voltage to linear */
+ for ( ii = 0; ii < 256; ii++ )
+ gamma_ramp[ii] = (unsigned short)( pow( (double)ii/255.0f, gamma_value )*gmax );
+
+ /* linear to voltage */
+ for ( ii = 0; ii < gmax; ii++ )
+ gamma_ramp_inv[ii] = (unsigned char)( pow( (double)ii/gmax, gamma_inv ) * 255.0f );
+ }
+}
+
+
+/* clear the cache
+ */
+static void
+gblender_clear( GBlender blender )
+{
+ int nn;
+ GBlenderKey keys = blender->keys;
+
+ if ( blender->channels )
+ {
+ GBlenderChanKey chan_keys = (GBlenderChanKey) blender->keys;
+
+ for ( nn = 0; nn < GBLENDER_KEY_COUNT; nn++ )
+ chan_keys[nn].index = -1;
+ }
+ else
+ {
+ for ( nn = 0; nn < GBLENDER_KEY_COUNT; nn++ )
+ keys[nn].cells = NULL;
+ }
+}
+
+GBLENDER_APIDEF( void )
+gblender_reset( GBlender blender )
+{
+ gblender_clear( blender );
+
+ blender->cache_r_back = -1;
+ blender->cache_r_fore = -1;
+ blender->cache_r_cells = 0;
+
+ blender->cache_r_back = -1;
+ blender->cache_r_fore = -1;
+ blender->cache_r_cells = 0;
+
+ blender->cache_back = 0;
+ blender->cache_fore = 0xFFFFFF;
+ blender->cache_cells = gblender_lookup( blender,
+ blender->cache_back,
+ blender->cache_fore );
+
+#ifdef GBLENDER_STATS
+ blender->stat_hits = 0;
+ blender->stat_lookups = 0;
+ blender->stat_keys = 0;
+ blender->stat_clears = 0;
+#endif
+}
+
+GBLENDER_APIDEF( void )
+gblender_init( GBlender blender,
+ double gamma_value )
+{
+ blender->channels = 0;
+
+ gblender_set_gamma_table ( gamma_value,
+ blender->gamma_ramp,
+ blender->gamma_ramp_inv );
+
+ gblender_reset( blender );
+}
+
+/* recompute the grade levels of a given key
+ */
+static void
+gblender_reset_key( GBlender blender,
+ GBlenderKey key )
+{
+ GBlenderPixel back = key->background;
+ GBlenderPixel fore = key->foreground;
+ GBlenderCell* gr = key->cells;
+ int nn;
+ int gmax = (256 << GBLENDER_GAMMA_SHIFT)-1;
+
+ const unsigned char* gamma_ramp_inv = blender->gamma_ramp_inv;
+ const unsigned short* gamma_ramp = blender->gamma_ramp;
+
+ int r1,g1,b1,r2,g2,b2;
+
+ r1 = ( back >> 16 ) & 255;
+ g1 = ( back >> 8 ) & 255;
+ b1 = ( back ) & 255;
+
+ r2 = ( fore >> 16 ) & 255;
+ g2 = ( fore >> 8 ) & 255;
+ b2 = ( fore ) & 255;
+
+#ifdef GBLENDER_STORE_BYTES
+ gr[0] = (unsigned char)r1;
+ gr[1] = (unsigned char)g1;
+ gr[2] = (unsigned char)b1;
+ gr += 3;
+#else
+ gr[0] = back;
+ gr += 1;
+#endif
+
+ r1 = gamma_ramp[r1];
+ g1 = gamma_ramp[g1];
+ b1 = gamma_ramp[b1];
+
+ r2 = gamma_ramp[r2];
+ g2 = gamma_ramp[g2];
+ b2 = gamma_ramp[b2];
+
+ for ( nn = 1; nn < GBLENDER_SHADE_COUNT; nn++ )
+ {
+ int a = (nn << GBLENDER_SHADE_BITS);
+ int r = ((r2-r1)*a + 128);
+ int g = ((g2-g1)*a + 128);
+ int b = ((g2-g1)*a + 128);
+
+ r = (r + (r >> 8)) >> 8;
+ g = (g + (g >> 8)) >> 8;
+ b = (b + (b >> 8)) >> 8;
+
+ r += r1;
+ g += g1;
+ b += b1;
+
+#if 0
+ r = ( r | -(r >> 8) ) & 255;
+ g = ( g | -(g >> 8) ) & 255;
+ b = ( b | -(b >> 8) ) & 255;
+#else
+ if ( r < 0 ) r = 0; else if ( r > gmax ) r = gmax;
+ if ( g < 0 ) g = 0; else if ( g > gmax ) g = gmax;
+ if ( b < 0 ) b = 0; else if ( b > gmax ) b = gmax;
+#endif
+
+ r = gamma_ramp_inv[r];
+ g = gamma_ramp_inv[g];
+ b = gamma_ramp_inv[b];
+
+#ifdef GBLENDER_STORE_BYTES
+ gr[0] = (unsigned char)r;
+ gr[1] = (unsigned char)g;
+ gr[2] = (unsigned char)b;
+ gr += 3;
+#else
+ gr[0] = (( r & 255 ) << 16) |
+ (( g & 255 ) << 8 ) |
+ (( b & 255 ) ) ;
+ gr ++;
+#endif
+ }
+}
+
+ /* lookup the grades of a given (background,foreground) couple
+ */
+GBLENDER_APIDEF( GBlenderCell* )
+gblender_lookup( GBlender blender,
+ GBlenderPixel background,
+ GBlenderPixel foreground )
+{
+ int idx, idx0;
+ GBlenderKey key;
+
+#ifdef GBLENDER_STATS
+ blender->stat_hits--;
+ blender->stat_lookups++;
+#endif
+
+ if ( blender->channels )
+ {
+ /* set to normal mode */
+ blender->channels = 0;
+ gblender_reset( blender );
+ }
+
+ idx0 = ( background + foreground*63 ) % GBLENDER_KEY_COUNT;
+ idx = idx0;
+ do
+ {
+ key = blender->keys + idx;
+
+ if ( key->cells == NULL )
+ goto NewNode;
+
+ if ( key->background == background &&
+ key->foreground == foreground )
+ goto Exit;
+
+ idx = (idx+1) % GBLENDER_KEY_COUNT;
+ }
+ while ( idx != idx0 );
+
+ /* the cache is full, clear it completely
+ */
+#ifdef GBLENDER_STATS
+ blender->stat_clears++;
+ gblender_clear( blender );
+#endif
+
+NewNode:
+ key->background = background;
+ key->foreground = foreground;
+ key->cells = blender->cells + \
+ idx0*(GBLENDER_SHADE_COUNT*GBLENDER_CELL_SIZE);
+
+ gblender_reset_key( blender, key );
+
+#ifdef GBLENDER_STATS
+ blender->stat_keys++;
+#endif
+
+Exit:
+ return key->cells;
+}
+
+
+static void
+gblender_reset_channel_key( GBlender blender,
+ GBlenderChanKey key )
+{
+ int back = key->backfore & 255;
+ int fore = (key->backfore >> 8) & 255;
+ unsigned char* gr = (unsigned char*)blender->cells + key->index;
+ int nn;
+
+ const unsigned char* gamma_ramp_inv = blender->gamma_ramp_inv;
+ const unsigned short* gamma_ramp = blender->gamma_ramp;
+
+ int r1,r2;
+ int gmax = (256 << GBLENDER_GAMMA_SHIFT)-1;
+
+ r1 = back;
+ r2 = fore;
+
+ gr[0] = r1;
+ gr++;
+
+
+ r1 = gamma_ramp[r1];
+ r2 = gamma_ramp[r2];
+
+ for ( nn = 1; nn < GBLENDER_SHADE_COUNT; nn++ )
+ {
+ int a = (nn << GBLENDER_SHADE_BITS);
+ int r = ((r2-r1)*a + 128);
+
+ r = (r + (r >> 8)) >> 8;
+ r += r1;
+ if ( r < 0 ) r = 0; else if ( r > gmax ) r = gmax;
+ r = gamma_ramp_inv[r];
+
+ gr[0] = (unsigned char)r;
+ gr++;
+ }
+}
+
+
+GBLENDER_APIDEF( unsigned char* )
+gblender_lookup_channel( GBlender blender,
+ int background,
+ int foreground )
+{
+ int idx, idx0;
+ unsigned short backfore = (unsigned short)((foreground << 8) | background);
+ GBlenderChanKey key;
+
+#ifdef GBLENDER_STATS
+ blender->stat_hits--;
+ blender->stat_lookups++;
+#endif
+
+ if ( !blender->channels )
+ {
+ /* set to normal mode */
+ blender->channels = 1;
+ gblender_reset( blender );
+ }
+
+ idx0 = ( background + foreground*63 ) % (2*GBLENDER_KEY_COUNT);
+ idx = idx0;
+ do
+ {
+ key = (GBlenderChanKey)blender->keys + idx;
+
+ if ( key->index < 0 )
+ goto NewNode;
+
+ if ( key->backfore == backfore )
+ goto Exit;
+
+ idx = (idx+1) % (2*GBLENDER_KEY_COUNT);
+ }
+ while ( idx != idx0 );
+
+ /* the cache is full, clear it completely
+ */
+#ifdef GBLENDER_STATS
+ blender->stat_clears++;
+ gblender_clear( blender );
+#endif
+
+NewNode:
+ key->backfore = backfore;
+ key->index = (signed short)( idx0 * GBLENDER_SHADE_COUNT );
+
+ gblender_reset_channel_key( blender, key );
+
+#ifdef GBLENDER_STATS
+ blender->stat_keys++;
+#endif
+
+Exit:
+ return (unsigned char*)blender->cells + key->index;
+}
+
+
+
+#ifdef GBLENDER_STATS
+#include <stdio.h>
+GBLENDER_APIDEF( void )
+gblender_dump_stats( GBlender blender )
+{
+ printf( "hits = %ld, miss1 = %ld, miss2 = %ld, rate1=%.2f%%, rate2=%.2f%%\n",
+ blender->stat_hits,
+ blender->stat_lookups,
+ blender->stat_keys,
+ (100.0*blender->stat_hits) / (double)(blender->stat_hits + blender->stat_lookups),
+ (100.0*blender->stat_lookups) / (double)( blender->stat_lookups + blender->stat_keys)
+ );
+}
+#endif
diff --git a/kernel/kls_ttf/ftview/gblender.h b/kernel/kls_ttf/ftview/gblender.h
new file mode 100644
index 0000000..b519b3c
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblender.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+ *
+ * Gamma-correct alpha blending of text
+ *
+ * (C) 2004 David Turner
+ *
+ */
+
+#ifndef __GBLENDER_H__
+#define __GBLENDER_H__
+
+#ifndef GBLENDER_API
+#define GBLENDER_API(x) extern x
+#endif
+
+#ifndef GBLENDER_APIDEF
+#define GBLENDER_APIDEF(x) x
+#endif
+
+#define GBLENDER_SHADE_BITS 4 /* must be <= 7 !! */
+#define GBLENDER_SHADE_COUNT ( 1 << GBLENDER_SHADE_BITS )
+#define GBLENDER_SHADE_INDEX(n) ((n + (GBLENDER_SHADE_COUNT/2)) >> GBLENDER_SHADE_BITS)
+#define GBLENDER_KEY_COUNT 256
+#define GBLENDER_GAMMA_SHIFT 2
+
+#define xGBLENDER_STORE_BYTES /* define this to store (R,G,B) values on 3 \
+ * bytes, instead of a single 32-bit integer.\
+ * surprisingly, this can speed up \
+ * the blender on certain machines. \
+ * Go figure what's really happenning though :-) \
+ */
+
+#define GBLENDER_STATS /* define this to collect statistics in the \
+ * blender \
+ */
+
+ typedef unsigned int GBlenderPixel; /* needs 32-bits here !! */
+
+#ifdef GBLENDER_STORE_BYTES
+ typedef unsigned char GBlenderCell;
+# define GBLENDER_CELL_SIZE 3
+#else
+ typedef GBlenderPixel GBlenderCell;
+# define GBLENDER_CELL_SIZE 1
+#endif
+
+
+ typedef struct
+ {
+ GBlenderPixel background;
+ GBlenderPixel foreground;
+ GBlenderCell* cells;
+
+ } GBlenderKeyRec, *GBlenderKey;
+
+
+ typedef struct
+ {
+ unsigned short backfore; /* (fore << 8) | back */
+ signed short index; /* offset in (unsigned char*)cells */
+
+ } GBlenderChanKeyRec, *GBlenderChanKey;
+
+
+ typedef struct GBlenderRec_
+ {
+ GBlenderKeyRec keys [ GBLENDER_KEY_COUNT ];
+ GBlenderCell cells[ GBLENDER_KEY_COUNT*GBLENDER_SHADE_COUNT*GBLENDER_CELL_SIZE ];
+
+ /* a small cache for normal modes
+ */
+ GBlenderPixel cache_back;
+ GBlenderPixel cache_fore;
+ GBlenderCell* cache_cells;
+
+ /* a small cache for RGB channels modes
+ */
+ int cache_r_back;
+ int cache_r_fore;
+ unsigned char* cache_r_cells;
+
+ int cache_g_back;
+ int cache_g_fore;
+ unsigned char* cache_g_cells;
+
+ int cache_b_back;
+ int cache_b_fore;
+ unsigned char* cache_b_cells;
+
+ /* are we in color or channel mode ?
+ */
+ int channels;
+
+ /* the gamma table
+ */
+ unsigned short gamma_ramp[256]; /* voltage to linear */
+ unsigned char gamma_ramp_inv[256 << GBLENDER_GAMMA_SHIFT]; /* linear to voltage */
+
+#ifdef GBLENDER_STATS
+ long stat_hits; /* number of direct hits */
+ long stat_lookups; /* number of table lookups */
+ long stat_keys; /* number of table key recomputation */
+ long stat_clears; /* number of table clears */
+#endif
+
+ } GBlenderRec, *GBlender;
+
+
+ /* initialize with a given gamma */
+ GBLENDER_API( void )
+ gblender_init( GBlender blender,
+ double gamma );
+
+
+ /* clear blender, and reset stats */
+ GBLENDER_API( void )
+ gblender_reset( GBlender reset );
+
+
+ /* lookup a cell range for a given (background,foreground) pair
+ */
+ GBLENDER_API( GBlenderCell* )
+ gblender_lookup( GBlender blender,
+ GBlenderPixel background,
+ GBlenderPixel foreground );
+
+ GBLENDER_API( unsigned char* )
+ gblender_lookup_channel( GBlender blender,
+ int background,
+ int foreground );
+
+#ifdef GBLENDER_STATS
+ GBLENDER_API( void )
+ gblender_dump_stats( GBlender blender );
+#else
+# define gblender_dump_stats(b) do { } while (0);
+#endif
+
+
+ /* no final `;'! */
+#define GBLENDER_VARS(_gb,_fore) \
+ GBlenderPixel _gback = (_gb)->cache_back; \
+ GBlenderCell* _gcells = ( (_fore) == (_gb)->cache_fore ? (_gb)->cache_cells : gblender_lookup( (_gb), _gback, _fore ) ); \
+ GBlenderPixel _gfore = (_fore)
+
+#define GBLENDER_CLOSE(_gb) \
+ (_gb)->cache_back = _gback; \
+ (_gb)->cache_fore = _gfore; \
+ (_gb)->cache_cells = _gcells;
+
+
+
+ /* no final `;'! */
+#define GBLENDER_CHANNEL_VARS(_gb,_rfore,_gfore,_bfore) \
+ int _grback = (_gb)->cache_r_back; \
+ unsigned char* _grcells = ( (_rfore) == (_gb)->cache_r_fore ? (_gb)->cache_r_cells : gblender_lookup_channel( (_gb), _grback, _rfore )); \
+ int _grfore = (_rfore); \
+ int _ggback = (_gb)->cache_g_back; \
+ unsigned char* _ggcells = ( (_gfore) == (_gb)->cache_g_fore ? (_gb)->cache_g_cells : gblender_lookup_channel( (_gb), _ggback, _gfore )); \
+ int _ggfore = (_rfore); \
+ int _gbback = (_gb)->cache_b_back; \
+ unsigned char* _gbcells = ( (_bfore) == (_gb)->cache_b_fore ? (_gb)->cache_b_cells : gblender_lookup_channel( (_gb), _gbback, _bfore )); \
+ int _gbfore = (_bfore)
+
+#define GBLENDER_CHANNEL_CLOSE(_gb) \
+ (_gb)->cache_r_back = _grback; \
+ (_gb)->cache_r_fore = _grfore; \
+ (_gb)->cache_r_cells = _grcells; \
+ (_gb)->cache_g_back = _ggback; \
+ (_gb)->cache_g_fore = _ggfore; \
+ (_gb)->cache_g_cells = _ggcells; \
+ (_gb)->cache_b_back = _gbback; \
+ (_gb)->cache_b_fore = _gbfore; \
+ (_gb)->cache_b_cells = _gbcells;
+
+
+#ifdef GBLENDER_STATS
+#define GBLENDER_STAT_HIT(gb) (gb)->stat_hits++
+#else
+#define GBLENDER_STAT_HIT(gb) /* nothing */
+#endif
+
+#define GBLENDER_LOOKUP(gb,back) \
+ GBLENDER_STAT_HIT(gb); \
+ if ( _gback != (GBlenderPixel)(back) ) \
+ { \
+ _gback = (GBlenderPixel)(back); \
+ _gcells = gblender_lookup( (gb), _gback, _gfore ); \
+ }
+
+#define GBLENDER_LOOKUP_R(gb,back) \
+ GBLENDER_STAT_HIT(gb); \
+ if ( _grback != (int)(back) ) \
+ { \
+ _grback = (GBlenderPixel)(back); \
+ _grcells = gblender_lookup_channel( (gb), _grback, _grfore ); \
+ }
+
+#define GBLENDER_LOOKUP_G(gb,back) \
+ GBLENDER_STAT_HIT(gb); \
+ if ( _ggback != (int)(back) ) \
+ { \
+ _ggback = (GBlenderPixel)(back); \
+ _ggcells = gblender_lookup_channel( (gb), _ggback, _ggfore ); \
+ }
+
+#define GBLENDER_LOOKUP_B(gb,back) \
+ GBLENDER_STAT_HIT(gb); \
+ if ( _gbback != (int)(back) ) \
+ { \
+ _gbback = (GBlenderPixel)(back); \
+ _gbcells = gblender_lookup_channel( (gb), _gbback, _gbfore ); \
+ }
+
+
+#endif /* __GBENCH_CACHE_H__ */
diff --git a/kernel/kls_ttf/ftview/gblhbgr.h b/kernel/kls_ttf/ftview/gblhbgr.h
new file mode 100644
index 0000000..a2740ab
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblhbgr.h
@@ -0,0 +1,74 @@
+ GBLENDER_CHANNEL_VARS(blender,r,g,b);
+
+ int h = blit->height;
+ const unsigned char* src_line = blit->src_line;
+ unsigned char* dst_line = blit->dst_line;
+
+ do
+ {
+ const unsigned char* src = src_line + blit->src_x*3;
+ unsigned char* dst = dst_line + blit->dst_x*GDST_INCR;
+ int w = blit->width;
+
+ do
+ {
+ int ab = GBLENDER_SHADE_INDEX(src[0]);
+ int ag = GBLENDER_SHADE_INDEX(src[1]);
+ int ar = GBLENDER_SHADE_INDEX(src[2]);
+ int aa = (ar << 16) | (ag << 8) | ab;
+
+ if ( aa == 0 )
+ {
+ /* nothing */
+ }
+ else if ( aa == ((GBLENDER_SHADE_COUNT << 16) |
+ (GBLENDER_SHADE_COUNT << 8) |
+ (GBLENDER_SHADE_COUNT) ) )
+ {
+ GDST_COPY(dst);
+ }
+ else
+ {
+ GBlenderPixel back;
+ int pix_r, pix_g, pix_b;
+
+ GDST_READ(dst,back);
+
+ {
+ int back_r = (back >> 16) & 255;
+
+ GBLENDER_LOOKUP_R( blender, back_r );
+
+ pix_r = _grcells[ar];
+ }
+
+ {
+ int back_g = (back >> 8) & 255;
+
+ GBLENDER_LOOKUP_G( blender, back_g );
+
+ pix_g = _ggcells[ag];
+ }
+
+ {
+ int back_b = (back) & 255;
+
+ GBLENDER_LOOKUP_B( blender, back_b );
+
+ pix_b = _gbcells[ab];
+ }
+
+ GDST_STOREC(dst,pix_r,pix_g,pix_b);
+ }
+
+ src += 3;
+ dst += GDST_INCR;
+ }
+ while (--w > 0);
+
+ src_line += blit->src_pitch;
+ dst_line += blit->dst_pitch;
+ }
+ while (--h > 0);
+
+ GBLENDER_CHANNEL_CLOSE(blender);
diff --git a/kernel/kls_ttf/ftview/gblhrgb.h b/kernel/kls_ttf/ftview/gblhrgb.h
new file mode 100644
index 0000000..930a6c9
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblhrgb.h
@@ -0,0 +1,76 @@
+
+ GBLENDER_CHANNEL_VARS(blender,r,g,b);
+
+ int h = blit->height;
+ const unsigned char* src_line = blit->src_line;
+ unsigned char* dst_line = blit->dst_line;
+
+ do
+ {
+ const unsigned char* src = src_line + blit->src_x*3;
+ unsigned char* dst = dst_line + blit->dst_x*GDST_INCR;
+ int w = blit->width;
+
+ do
+ {
+ int ar = GBLENDER_SHADE_INDEX(src[0]);
+ int ag = GBLENDER_SHADE_INDEX(src[1]);
+ int ab = GBLENDER_SHADE_INDEX(src[2]);
+ int aa = (ar << 16) | (ag << 8) | ab;
+
+ if ( aa == 0 )
+ {
+ /* nothing */
+ }
+ else if ( aa == ((GBLENDER_SHADE_COUNT << 16) |
+ (GBLENDER_SHADE_COUNT << 8) |
+ (GBLENDER_SHADE_COUNT) ) )
+ {
+ GDST_COPY(dst);
+ }
+ else
+ {
+ GBlenderPixel back;
+ int pix_r, pix_g, pix_b;
+
+ GDST_READ(dst,back);
+
+ {
+ int back_r = (back >> 16) & 255;
+
+ GBLENDER_LOOKUP_R( blender, back_r );
+
+ pix_r = _grcells[ar];
+ }
+
+ {
+ int back_g = (back >> 8) & 255;
+
+ GBLENDER_LOOKUP_G( blender, back_g );
+
+ pix_g = _ggcells[ag];
+ }
+
+ {
+ int back_b = (back) & 255;
+
+ GBLENDER_LOOKUP_B( blender, back_b );
+
+ pix_b = _gbcells[ab];
+ }
+
+ GDST_STOREC(dst,pix_r,pix_g,pix_b);
+ }
+
+ src += 3;
+ dst += GDST_INCR;
+ }
+ while (--w > 0);
+
+ src_line += blit->src_pitch;
+ dst_line += blit->dst_pitch;
+ }
+ while (--h > 0);
+
+ GBLENDER_CHANNEL_CLOSE(blender);
+
diff --git a/kernel/kls_ttf/ftview/gblvbgr.h b/kernel/kls_ttf/ftview/gblvbgr.h
new file mode 100644
index 0000000..48565ff
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblvbgr.h
@@ -0,0 +1,76 @@
+
+ GBLENDER_CHANNEL_VARS(blender,r,g,b);
+
+ int h = blit->height;
+ const unsigned char* src_line = blit->src_line;
+ int src_pitch = blit->src_pitch;
+ unsigned char* dst_line = blit->dst_line;
+
+ do
+ {
+ const unsigned char* src = src_line + blit->src_x;
+ unsigned char* dst = dst_line + blit->dst_x*GDST_INCR;
+ int w = blit->width;
+
+ do
+ {
+ int ab = GBLENDER_SHADE_INDEX(src[0]);
+ int ag = GBLENDER_SHADE_INDEX(src[src_pitch]);
+ int ar = GBLENDER_SHADE_INDEX(src[src_pitch << 1]);
+ GBlenderPixel aa = ((GBlenderPixel)ar << 16) | (ag << 8) | ab;
+
+ if ( aa == 0 )
+ {
+ /* nothing */
+ }
+ else if ( aa == ((GBLENDER_SHADE_COUNT << 16) |
+ (GBLENDER_SHADE_COUNT << 8) |
+ (GBLENDER_SHADE_COUNT) ) )
+ {
+ GDST_COPY(dst);
+ }
+ else
+ {
+ GBlenderPixel back;
+ int pix_r, pix_g, pix_b;
+
+ GDST_READ(dst,back);
+
+ {
+ int back_r = (back >> 16) & 255;
+
+ GBLENDER_LOOKUP_R( blender, back_r );
+
+ pix_r = _grcells[ar];
+ }
+
+ {
+ int back_g = (back >> 8) & 255;
+
+ GBLENDER_LOOKUP_G( blender, back_g );
+
+ pix_g = _ggcells[ag];
+ }
+
+ {
+ int back_b = (back) & 255;
+
+ GBLENDER_LOOKUP_B( blender, back_b );
+
+ pix_b = _gbcells[ab];
+ }
+
+ GDST_STOREC(dst,pix_r,pix_g,pix_b);
+ }
+
+ src += 1;
+ dst += GDST_INCR;
+ }
+ while (--w > 0);
+
+ src_line += blit->src_pitch*3;
+ dst_line += blit->dst_pitch;
+ }
+ while (--h > 0);
+
+ GBLENDER_CHANNEL_CLOSE(blender);
diff --git a/kernel/kls_ttf/ftview/gblvrgb.h b/kernel/kls_ttf/ftview/gblvrgb.h
new file mode 100644
index 0000000..d31aaa9
--- /dev/null
+++ b/kernel/kls_ttf/ftview/gblvrgb.h
@@ -0,0 +1,76 @@
+
+ GBLENDER_CHANNEL_VARS(blender,r,g,b);
+
+ int h = blit->height;
+ const unsigned char* src_line = blit->src_line;
+ int src_pitch = blit->src_pitch;
+ unsigned char* dst_line = blit->dst_line;
+
+ do
+ {
+ const unsigned char* src = src_line + blit->src_x;
+ unsigned char* dst = dst_line + blit->dst_x*GDST_INCR;
+ int w = blit->width;
+
+ do
+ {
+ int ar = GBLENDER_SHADE_INDEX(src[0]);
+ int ag = GBLENDER_SHADE_INDEX(src[src_pitch]);
+ int ab = GBLENDER_SHADE_INDEX(src[src_pitch << 1]);
+ GBlenderPixel aa = ((GBlenderPixel)ar << 16) | (ag << 8) | ab;
+
+ if ( aa == 0 )
+ {
+ /* nothing */
+ }
+ else if ( aa == ((GBLENDER_SHADE_COUNT << 16) |
+ (GBLENDER_SHADE_COUNT << 8) |
+ (GBLENDER_SHADE_COUNT) ) )
+ {
+ GDST_COPY(dst);
+ }
+ else
+ {
+ GBlenderPixel back;
+ int pix_r, pix_g, pix_b;
+
+ GDST_READ(dst,back);
+
+ {
+ int back_r = (back >> 16) & 255;
+
+ GBLENDER_LOOKUP_R( blender, back_r );
+
+ pix_r = _grcells[ar];
+ }
+
+ {
+ int back_g = (back >> 8) & 255;
+
+ GBLENDER_LOOKUP_G( blender, back_g );
+
+ pix_g = _ggcells[ag];
+ }
+
+ {
+ int back_b = (back) & 255;
+
+ GBLENDER_LOOKUP_B( blender, back_b );
+
+ pix_b = _gbcells[ab];
+ }
+
+ GDST_STOREC(dst,pix_r,pix_g,pix_b);
+ }
+
+ src += 1;
+ dst += GDST_INCR;
+ }
+ while (--w > 0);
+
+ src_line += blit->src_pitch*3;
+ dst_line += blit->dst_pitch;
+ }
+ while (--h > 0);
+
+ GBLENDER_CHANNEL_CLOSE(blender);
diff --git a/kernel/kls_ttf/ftview/graph.h b/kernel/kls_ttf/ftview/graph.h
new file mode 100644
index 0000000..81f1716
--- /dev/null
+++ b/kernel/kls_ttf/ftview/graph.h
@@ -0,0 +1,653 @@
+/***************************************************************************
+ *
+ * graph.h
+ *
+ * Graphics Subsystem interface
+ *
+ * Copyright 1999, 2000, 2001, 2002
+ * - The FreeType Development Team - www.freetype.org
+ *
+ ***************************************************************************/
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include "grevents.h"
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** GENERAL DEFINITIONS AND BLITTING ROUTINES ********/
+ /******** ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /* define the global error variable */
+ extern int grError;
+
+ /* initialisation */
+ extern int grInit( void );
+
+ /* finalisation */
+ extern void grDone( void );
+
+
+ /* pixel mode constants */
+ typedef enum grPixelMode
+ {
+ gr_pixel_mode_none = 0,
+ gr_pixel_mode_mono, /* monochrome bitmaps */
+ gr_pixel_mode_pal4, /* 4-bit paletted - 16 colors */
+ gr_pixel_mode_pal8, /* 8-bit paletted - 256 colors */
+ gr_pixel_mode_gray, /* 8-bit gray levels */
+ gr_pixel_mode_rgb555, /* 15-bits mode - 32768 colors */
+ gr_pixel_mode_rgb565, /* 16-bits mode - 65536 colors */
+ gr_pixel_mode_rgb24, /* 24-bits mode - 16 million colors */
+ gr_pixel_mode_rgb32, /* 32-bits mode - 16 million colors */
+ gr_pixel_mode_lcd, /* horizontal RGB-decimated */
+ gr_pixel_mode_lcdv, /* vertical RGB-decimated */
+ gr_pixel_mode_lcd2, /* horizontal BGR-decimated */
+ gr_pixel_mode_lcdv2, /* vertical BGR-decimated */
+
+ gr_pixel_mode_max /* don't remove */
+
+ } grPixelMode;
+
+
+ /* forward declaration of the surface class */
+ typedef struct grSurface_ grSurface;
+
+
+ /*********************************************************************
+ *
+ * <Struct>
+ * grBitmap
+ *
+ * <Description>
+ * a simple bitmap descriptor
+ *
+ * <Fields>
+ * rows :: height in pixels
+ * width :: width in pixels
+ * pitch :: + or - the number of bytes per row
+ * mode :: pixel mode of bitmap buffer
+ * grays :: number of grays in palette for PAL8 mode. 0 otherwise
+ * buffer :: pointer to pixel buffer
+ *
+ * <Note>
+ * the 'pitch' is positive for downward flows, and negative otherwise
+ * Its absolute value is always the number of bytes taken by each
+ * bitmap row.
+ *
+ * All drawing operations will be performed within the first
+ * "width" pixels of each row (clipping is always performed).
+ *
+ ********************************************************************/
+
+ typedef struct grBitmap_
+ {
+ int rows;
+ int width;
+ int pitch;
+ grPixelMode mode;
+ int grays;
+ unsigned char* buffer;
+
+ } grBitmap;
+
+
+
+ typedef long grPos;
+ typedef char grBool;
+
+ typedef struct grVector_
+ {
+ grPos x;
+ grPos y;
+
+ } grVector;
+
+
+ typedef union grColor_
+ {
+ long value;
+ unsigned char chroma[4];
+
+ } grColor;
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewBitmap
+ *
+ * <Description>
+ * creates a new bitmap
+ *
+ * <Input>
+ * pixel_mode :: the target surface's pixel_mode
+ * num_grays :: number of grays levels for PAL8 pixel mode
+ * width :: width in pixels
+ * height :: height in pixels
+ *
+ * <Output>
+ * bit :: descriptor of the new bitmap
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function really allocates a pixel buffer, zero it, then
+ * returns a descriptor for it.
+ *
+ * Call grDoneBitmap when you're done with it..
+ *
+ **********************************************************************/
+
+ extern int grNewBitmap( grPixelMode pixel_mode,
+ int num_grays,
+ int width,
+ int height,
+ grBitmap *bit );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grBlitGlyphToBitmap
+ *
+ * <Description>
+ * writes a given glyph bitmap to a target surface.
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * glyph :: handle to source glyph bitmap
+ * x :: position of left-most pixel of glyph image in target surface
+ * y :: position of top-most pixel of glyph image in target surface
+ * color :: color to be used to draw a monochrome glyph
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * There are only two supported source pixel modes : monochrome
+ * and gray. The 8-bit images can have any number of grays between
+ * 2 and 128, and conversions to the target surface is handled
+ * _automatically_.
+ *
+ * Note however that you should avoid blitting a gray glyph to a gray
+ * bitmap with fewer levels of grays, as this would much probably
+ * give unpleasant results..
+ *
+ * This function performs clipping
+ *
+ **********************************************************************/
+
+ extern int
+ grBlitGlyphToBitmap( grBitmap* target,
+ grBitmap* glyph,
+ grPos x,
+ grPos y,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grFillRectangle
+ *
+ * <Description>
+ * this function is used to fill a given rectangle on a surface
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: x coordinate of the top-left corner of the rectangle
+ * y :: y coordinate of the top-left corner of the rectangle
+ * width :: rectangle width in pixels
+ * height :: rectangle height in pixels
+ * color :: fill color
+ *
+ **********************************************************************/
+
+ extern void grFillRectangle( grBitmap* surface,
+ grPos x,
+ grPos y,
+ grPos width,
+ grPos height,
+ grColor color );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteCellChar
+ *
+ * <Description>
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a single 8x8 character on the target bitmap.
+ *
+ * <Input>
+ * target :: handle to target surface
+ * x :: x pixel position of character cell's top left corner
+ * y :: y pixel position of character cell's top left corner
+ * charcode :: Latin-1 character code
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteCellChar( grBitmap* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteCellString
+ *
+ * <Description>
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a string with the internal font
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * x :: x pixel position of string's top left corner
+ * y :: y pixel position of string's top left corner
+ * string :: Latin-1 text string
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteCellString( grBitmap* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color );
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grDoneBitmap
+ *
+ * <Description>
+ * destroys a bitmap
+ *
+ * <Input>
+ * bitmap :: handle to bitmap descriptor
+ *
+ * <Note>
+ * This function does NOT release the bitmap descriptor, only
+ * the pixel buffer.
+ *
+ **********************************************************************/
+
+ extern void grDoneBitmap( grBitmap* bit );
+
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** DEVICE-SPECIFIC DEFINITIONS AND ROUTINES ********/
+ /******** ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /* forward declaration - the definition of grDevice is not visible */
+ /* to clients.. */
+ typedef struct grDevice_ grDevice;
+
+
+ /**********************************************************************
+ *
+ * <Struct>
+ * grDeviceChain
+ *
+ * <Description>
+ * a simple structure used to implement a linked list of
+ * graphics device descriptors. The list is called a
+ * "device chain"
+ *
+ * <Fields>
+ * name :: ASCII name of the device, e.g. "x11", "os2pm", etc..
+ * device :: handle to the device descriptor.
+ * next :: next element in chain
+ *
+ * <Note>
+ * the 'device' field is a blind pointer; it is thus unusable by
+ * client applications..
+ *
+ **********************************************************************/
+
+ typedef struct grDeviceChain_ grDeviceChain;
+
+ struct grDeviceChain_
+ {
+ const char* name;
+ grDevice* device;
+ grDeviceChain* next;
+ };
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grInitDevices
+ *
+ * <Description>
+ * This function is in charge of initialising all system-specific
+ * devices. A device is responsible for creating and managing one
+ * or more "surfaces". A surface is either a window or a screen,
+ * depending on the system.
+ *
+ * <Return>
+ * a pointer to the first element of a device chain. The chain can
+ * be parsed to find the available devices on the current system
+ *
+ * <Note>
+ * If a device cannot be initialised correctly, it is not part of
+ * the device chain returned by this function. For example, if an
+ * X11 device was compiled in the library, it will be part of
+ * the returned device chain only if a connection to the display
+ * could be establisged
+ *
+ * If no driver could be initialised, this function returns NULL.
+ *
+ **********************************************************************/
+
+ extern
+ grDeviceChain* grInitDevices( void );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grGetDeviceModes
+ *
+ * <Description>
+ * queries the available pixel modes for a device.
+ *
+ * <Input>
+ * device_name :: name of device to be used. 0 for the default
+ * device. For a list of available devices, see
+ * grInitDevices.
+ *
+ * <Output>
+ * num_modes :: number of available modes. 0 in case of error,
+ * which really is an invalid device name.
+ *
+ * pixel_modes :: array of available pixel modes for this device
+ * this table is internal to the device and should
+ * not be freed by client applications.
+ *
+ * <Return>
+ * error code. 0 means success. invalid device name otherwise
+ *
+ * <Note>
+ * All drivers are _required_ to support at least the following
+ * pixel formats :
+ *
+ * - gr_pixel_mode_mono : i.e. monochrome bitmaps
+ * - gr_pixel_mode_gray : with any number of gray levels between
+ * 2 and 256.
+ *
+ * the pixel modes do not provide the number of grays in the case
+ * of "gray" devices. You should try to create a surface with the
+ * maximal number (256, that is) and see the value returned in
+ * the bitmap descriptor.
+ *
+ **********************************************************************/
+
+ extern void grGetDeviceModes( const char* device_name,
+ int *num_modes,
+ grPixelMode* *pixel_modes );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewSurface
+ *
+ * <Description>
+ * creates a new device-specific surface. A surface is either
+ * a window or a screen, depending on the device.
+ *
+ * <Input>
+ * device :: name of the device to use. A value of NULL means
+ * the default device (which depends on the system).
+ * for a list of available devices, see grInitDevices.
+ *
+ * <InOut>
+ * bitmap :: handle to a bitmap descriptor containing the
+ * requested pixel mode, number of grays and dimensions
+ * for the surface. the bitmap's 'pitch' and 'buffer'
+ * fields are ignored on input.
+ *
+ * On output, the bitmap describes the surface's image
+ * completely. It is possible to write directly in it
+ * with grBlitGlyphToBitmap, even though the use of
+ * grBlitGlyphToSurface is recommended.
+ *
+ * <Return>
+ * handle to the corresponding surface object. 0 in case of error
+ *
+ * <Note>
+ * All drivers are _required_ to support at least the following
+ * pixel formats :
+ *
+ * - gr_pixel_mode_mono : i.e. monochrome bitmaps
+ * - gr_pixel_mode_gray : with any number of gray levels between
+ * 2 and 256.
+ *
+ * This function might change the bitmap descriptor's fields. For
+ * example, when displaying a full-screen surface, the bitmap's
+ * dimensions will be set to those of the screen (e.g. 640x480
+ * or 800x600); also, the bitmap's 'buffer' field might point to
+ * the Video Ram depending on the mode requested..
+ *
+ * The surface contains a copy of the returned bitmap descriptor,
+ * you can thus discard the 'bitmap' parameter after the call.
+ *
+ **********************************************************************/
+
+ extern grSurface* grNewSurface( const char* device,
+ grBitmap* bitmap );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grRefreshRectangle
+ *
+ * <Description>
+ * this function is used to indicate that a given surface rectangle
+ * was modified and thus needs re-painting. It really is useful for
+ * windowed or gray surfaces.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: x coordinate of the top-left corner of the rectangle
+ * y :: y coordinate of the top-left corner of the rectangle
+ * width :: rectangle width in pixels
+ * height :: rectangle height in pixels
+ *
+ **********************************************************************/
+
+ extern void grRefreshRectangle( grSurface* surface,
+ grPos x,
+ grPos y,
+ grPos width,
+ grPos height );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grRefreshSurface
+ *
+ * <Description>
+ * a variation of grRefreshRectangle which repaints the whole surface
+ * to the screen.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ *
+ **********************************************************************/
+
+ extern void grRefreshSurface( grSurface* surface );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteSurfaceChar
+ *
+ * <Description>
+ * This function is equivalent to calling grWriteCellChar on the
+ * surface's bitmap, then invoking grRefreshRectangle.
+ *
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a single 8x8 character on the target bitmap.
+ *
+ * <Input>
+ * target :: handle to target surface
+ * x :: x pixel position of character cell's top left corner
+ * y :: y pixel position of character cell's top left corner
+ * charcode :: Latin-1 character code
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteSurfaceChar( grSurface* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteSurfaceString
+ *
+ * <Description>
+ * This function is equivalent to calling grWriteCellString on the
+ * surface's bitmap, then invoking grRefreshRectangle.
+ *
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a string with the internal font
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * x :: x pixel position of string's top left corner
+ * y :: y pixel position of string's top left corner
+ * string :: Latin-1 text string
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteSurfaceString( grSurface* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grSetTitle
+ *
+ * <Description>
+ * set the window title of a given windowed surface.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * title_string :: the new title
+ *
+ **********************************************************************/
+
+ extern void grSetTitle( grSurface* surface,
+ const char* title_string );
+
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grListenSurface
+ *
+ * <Description>
+ * listen the events for a given surface
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * event_mask :: the event mask (mode)
+ *
+ * <Output>
+ * event :: the returned event
+ *
+ * <Note>
+ * XXX : For now, only keypresses are supported.
+ *
+ **********************************************************************/
+
+ extern
+ int grListenSurface( grSurface* surface,
+ int event_mask,
+ grEvent *event );
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grSetGlyphGamma
+ *
+ * <Description>
+ * set the gamma-correction coefficient. This is only used to
+ * blit glyphs
+ *
+ * <Input>
+ * gamma :: gamma value. <= 0 to select sRGB transfer function
+ *
+ **********************************************************************/
+
+ extern
+ void grSetGlyphGamma( double gamma_value );
+
+/* */
+
+#endif /* GRAPH_H */
diff --git a/kernel/kls_ttf/ftview/grblit.cpp b/kernel/kls_ttf/ftview/grblit.cpp
new file mode 100644
index 0000000..18046ab
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grblit.cpp
@@ -0,0 +1,2068 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-1999, 2000, 2001, 2002 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* grblit.c: Support for blitting of bitmaps with various depth. */
+/* */
+/****************************************************************************/
+
+#include "grblit.h"
+#include "grobjs.h"
+
+#include <stdio.h>
+
+#define GRAY8
+
+ static
+ int compute_clips( grBlitter* blit,
+ int x_offset,
+ int y_offset )
+ {
+ int xmin, ymin, xmax, ymax, width, height, target_width;
+
+ /* perform clipping and setup variables */
+ width = blit->source.width;
+ height = blit->source.rows;
+
+ switch ( blit->source.mode )
+ {
+ case gr_pixel_mode_mono:
+ width = (width + 7) & -8;
+ break;
+
+ case gr_pixel_mode_pal4:
+ width = (width + 1) & -2;
+ break;
+
+ case gr_pixel_mode_lcd:
+ case gr_pixel_mode_lcd2:
+ width /= 3;
+ break;
+
+ case gr_pixel_mode_lcdv:
+ case gr_pixel_mode_lcdv2:
+ height /= 3;
+ break;
+
+ default:
+ ;
+ }
+
+ xmin = x_offset;
+ ymin = y_offset;
+ xmax = xmin + width-1;
+ ymax = ymin + height-1;
+
+ /* clip if necessary */
+ if ( width == 0 || height == 0 ||
+ xmax < 0 || xmin >= blit->target.width ||
+ ymax < 0 || ymin >= blit->target.rows )
+ return 1;
+
+ /* set up clipping and cursors */
+ blit->yread = 0;
+ if ( ymin < 0 )
+ {
+ blit->yread -= ymin;
+ height += ymin;
+ blit->ywrite = 0;
+ }
+ else
+ blit->ywrite = ymin;
+
+ if ( ymax >= blit->target.rows )
+ height -= ymax - blit->target.rows + 1;
+
+ blit->xread = 0;
+ if ( xmin < 0 )
+ {
+ blit->xread -= xmin;
+ width += xmin;
+ blit->xwrite = 0;
+ }
+ else
+ blit->xwrite = xmin;
+
+ target_width = blit->target.width;
+
+ switch ( blit->target.mode )
+ {
+ case gr_pixel_mode_mono:
+ target_width = (target_width + 7) & -8;
+ break;
+ case gr_pixel_mode_pal4:
+ target_width = (target_width + 1) & -2;
+ break;
+
+ default:
+ ;
+ }
+
+ blit->right_clip = xmax - target_width + 1;
+ if ( blit->right_clip > 0 )
+ width -= blit->right_clip;
+ else
+ blit->right_clip = 0;
+
+ blit->width = width;
+ blit->height = height;
+
+ /* set read and write to the top-left corner of the read */
+ /* and write areas before clipping. */
+
+ blit->read = blit->source.buffer;
+ blit->write = blit->target.buffer;
+
+ blit->read_line = blit->source.pitch;
+ blit->write_line = blit->target.pitch;
+
+ if ( blit->read_line < 0 )
+ blit->read -= (blit->source.rows-1) * blit->read_line;
+
+ if ( blit->write_line < 0 )
+ blit->write -= (blit->target.rows-1) * blit->write_line;
+
+ /* now go to the start line. Note that we do not move the */
+ /* x position yet, as this is dependent on the pixel format */
+ blit->read += blit->yread * blit->read_line;
+ blit->write += blit->ywrite * blit->write_line;
+
+ return 0;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_mono */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_mono( grBlitter* blit,
+ grColor color )
+ {
+ int shift, left_clip, x, y;
+ byte* read;
+ byte* write;
+
+ (void)color; /* unused argument */
+
+ left_clip = ( blit->xread > 0 );
+ shift = ( blit->xwrite - blit->xread ) & 7;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + (blit->xwrite >> 3);
+
+ if ( shift == 0 )
+ {
+ y = blit->height;
+ do
+ {
+ byte* _read = read;
+ byte* _write = write;
+
+ x = blit->width;
+
+ do
+ {
+ *_write++ |= *_read++;
+ x -= 8;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+ else
+ {
+ int first, last, count;
+
+
+ first = blit->xwrite >> 3;
+ last = (blit->xwrite + blit->width-1) >> 3;
+
+ count = last - first;
+
+ if ( blit->right_clip )
+ count++;
+
+ y = blit->height;
+
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ unsigned int old;
+ int shift2 = (8-shift);
+
+ if ( left_clip )
+ old = (*_read++) << shift2;
+ else
+ old = 0;
+
+ x = count;
+ while ( x > 0 )
+ {
+ unsigned char val;
+
+ val = *_read++;
+ *_write++ |= (unsigned char)( (val >> shift) | old );
+ old = val << shift2;
+ x--;
+ }
+
+ if ( !blit->right_clip )
+ *_write |= (unsigned char)old;
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+
+ } while ( y > 0 );
+ }
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_pal8 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_pal8( grBlitter* blit,
+ grColor color )
+ {
+ int x, y, shift;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + blit->xwrite;
+ shift = blit->xread & 7;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ unsigned long val = (*_read++ | 0x100) << shift;
+
+ x = blit->width;
+ do
+ {
+ if (val & 0x10000)
+ val = *_read++ | 0x100;
+
+ if ( val & 0x80 )
+ *_write = (unsigned char)color.value;
+
+ val <<= 1;
+ _write++;
+
+ } while ( --x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_pal4 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_pal4( grBlitter* blit,
+ grColor color )
+ {
+ int x, y, phase,shift;
+ unsigned char* read;
+ unsigned char* write;
+ unsigned int col;
+
+
+ col = color.value & 15;
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + (blit->xwrite >> 1);
+
+ /* now begin blit */
+ shift = blit->xread & 7;
+ phase = blit->xwrite & 1;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int _phase = phase;
+ unsigned long val = (*_read++ | 0x100) << shift;
+
+ x = blit->width;
+ do
+ {
+ if (val & 0x10000)
+ val = *_read++ | 0x100;
+
+ if ( val & 0x80 )
+ {
+ if ( _phase )
+ *_write = (unsigned char)((*_write & 0xF0) | col);
+ else
+ *_write = (unsigned char)((*_write & 0x0F) | (col << 4));
+ }
+
+ val <<= 1;
+
+ _write += _phase;
+ _phase ^= 1;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_rgb16 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_rgb16( grBlitter* blit,
+ grColor color )
+ {
+ int x, y,shift;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + blit->xwrite*2;
+ shift = blit->xread & 7;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ unsigned long val = (*_read++ | 0x100) << shift;
+
+ x = blit->width;
+ do
+ {
+ if (val & 0x10000)
+ val = *_read++ | 0x100;
+
+ if ( val & 0x80 )
+ *(short*)_write = (short)color.value;
+
+ val <<= 1;
+ _write +=2;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_rgb24 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_rgb24( grBlitter* blit,
+ grColor color )
+ {
+ int x, y, shift;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + blit->xwrite*3;
+ shift = blit->xread & 7;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ unsigned long val = (*_read++ | 0x100) << shift;
+
+ x = blit->width;
+ do
+ {
+ if (val & 0x10000)
+ val = *_read++ | 0x100;
+
+ if ( val & 0x80 )
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+
+ val <<= 1;
+ _write += 3;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_rgb32 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_rgb32( grBlitter* blit,
+ grColor color )
+ {
+ int x, y,shift;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + ( blit->xread >> 3 );
+ write = blit->write + blit->xwrite*4;
+ shift = blit->xread & 7;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ unsigned long val = ( *_read++ | 0x100L ) << shift;
+
+ x = blit->width;
+ do
+ {
+ if ( val & 0x10000 )
+ val = *_read++ | 0x100L;
+
+ if ( val & 0x80 )
+ {
+ /* this could be greatly optimized as */
+ /* */
+ /* *(long*)_write = color.value */
+ /* */
+ /* but it wouldn't work on 64-bits systems... stupid C types! */
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ _write[3] = color.chroma[3];
+ }
+
+ val <<= 1;
+ _write += 4;
+ x--;
+
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+
+ } while ( y > 0 );
+ }
+
+
+ static
+ const grBlitterFunc gr_mono_blitters[gr_pixel_mode_max] =
+ {
+ 0,
+ blit_mono_to_mono,
+ blit_mono_to_pal4,
+ blit_mono_to_pal8,
+ blit_mono_to_pal8,
+ blit_mono_to_rgb16,
+ blit_mono_to_rgb16,
+ blit_mono_to_rgb24,
+ blit_mono_to_rgb32
+ };
+
+
+ /*******************************************************************/
+ /* */
+ /* Saturation tables */
+ /* */
+ /*******************************************************************/
+
+ typedef struct grSaturation_
+ {
+ int count;
+ const byte* table;
+
+ } grSaturation;
+
+
+ static
+ const byte gr_saturation_5[8] = { 0, 1, 2, 3, 4, 4, 4, 4 };
+
+
+ static
+ const byte gr_saturation_17[32] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ };
+
+
+ static
+ grSaturation gr_saturations[ GR_MAX_SATURATIONS ] =
+ {
+ { 5, gr_saturation_5 },
+ { 17, gr_saturation_17 }
+ };
+
+ static
+ int gr_num_saturations = 2;
+
+ static
+ grSaturation* gr_last_saturation = gr_saturations;
+
+
+ extern
+ const byte* grGetSaturation( int num_grays )
+ {
+ /* first of all, scan the current saturations table */
+ grSaturation* sat = gr_saturations;
+ grSaturation* limit = sat + gr_num_saturations;
+
+ if ( num_grays < 2 )
+ {
+ grError = gr_err_bad_argument;
+ return 0;
+ }
+
+ for ( ; sat < limit; sat++ )
+ {
+ if ( sat->count == num_grays )
+ {
+ gr_last_saturation = sat;
+ return sat->table;
+ }
+ }
+
+ /* not found, simply create a new entry if there is room */
+ if (gr_num_saturations < GR_MAX_SATURATIONS)
+ {
+ int i;
+ const byte* table;
+
+ table = (const byte*)grAlloc( (3*num_grays-1)*sizeof(byte) );
+ if (!table) return 0;
+
+ sat->count = num_grays;
+ sat->table = table;
+
+ for ( i = 0; i < num_grays; i++, table++ )
+ *(unsigned char*)table = (unsigned char)i;
+
+ for ( i = 2*num_grays-1; i > 0; i--, table++ )
+ *(unsigned char*)table = (unsigned char)(num_grays-1);
+
+ gr_num_saturations++;
+ gr_last_saturation = sat;
+ return sat->table;
+ }
+ grError = gr_err_saturation_overflow;
+ return 0;
+ }
+
+
+
+ /*******************************************************************/
+ /* */
+ /* conversion tables */
+ /* */
+ /*******************************************************************/
+
+ typedef struct grConversion_
+ {
+ int target_grays;
+ int source_grays;
+ const byte* table;
+
+ } grConversion;
+
+
+
+ static
+ const byte gr_gray5_to_gray17[5] = { 0, 4, 8, 12, 16 };
+
+
+ static
+ const byte gr_gray5_to_gray128[5] = { 0, 32, 64, 96, 127 };
+
+
+ static
+ const unsigned char gr_gray17_to_gray128[17] =
+ {
+ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 127
+ };
+
+ static
+ grConversion gr_conversions[ GR_MAX_CONVERSIONS ] =
+ {
+ { 17, 5, gr_gray5_to_gray17 },
+ { 128, 5, gr_gray5_to_gray128 },
+ { 128, 17, gr_gray17_to_gray128 }
+ };
+
+ static
+ int gr_num_conversions = 3;
+
+ static
+ grConversion* gr_last_conversion = gr_conversions;
+
+
+ extern
+ const byte* grGetConversion( int target_grays,
+ int source_grays )
+ {
+ grConversion* conv = gr_conversions;
+ grConversion* limit = conv + gr_num_conversions;
+
+ if ( target_grays < 2 || source_grays < 2 )
+ {
+ grError = gr_err_bad_argument;
+ return 0;
+ }
+
+ /* otherwise, scan table */
+ for ( ; conv < limit; conv++ )
+ {
+ if ( conv->target_grays == target_grays &&
+ conv->source_grays == source_grays )
+ {
+ gr_last_conversion = conv;
+ return conv->table;
+ }
+ }
+
+ /* not found, add a new conversion to the table */
+ if (gr_num_conversions < GR_MAX_CONVERSIONS)
+ {
+ const byte* table;
+ int n;
+
+ table = (const byte*)grAlloc( source_grays*sizeof(byte) );
+ if (!table)
+ return 0;
+
+ conv->target_grays = target_grays;
+ conv->source_grays = source_grays;
+ conv->table = table;
+
+ for ( n = 0; n < source_grays; n++ )
+ ((unsigned char*)table)[n] = (unsigned char)(n*(target_grays-1) /
+ (source_grays-1));
+
+ gr_num_conversions++;
+ gr_last_conversion = conv;
+ return table;
+ }
+ grError = gr_err_conversion_overflow;
+ return 0;
+ }
+
+
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_gray */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_gray( grBlitter* blit,
+ const byte* saturation,
+ const byte* conversion )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ unsigned char max1;
+ unsigned char max2;
+
+ max1 = (unsigned char)(blit->source.grays-1);
+ max2 = (unsigned char)(blit->target.grays-1);
+
+ read = blit->read + blit->xread;
+ write = blit->write + blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+#ifdef GR_CONFIG_GRAY_SKIP_WHITE
+ unsigned char val = *_read;
+
+ if (val)
+ {
+ if (val == max)
+ *_write = max2;
+ else
+ *_write = saturation[ (int)*_write + conversion[ *_read ] ];
+ }
+#else
+ *_write = saturation[ (int)*_write + conversion[ *_read ] ];
+#endif
+ _write++;
+ _read++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_gray_simple */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_gray_simple( grBlitter* blit,
+ const byte* saturation )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ unsigned char max;
+
+ max = (unsigned char)(blit->source.grays-1);
+
+ read = blit->read + blit->xread;
+ write = blit->write + blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+#ifdef GR_CONFIG_GRAY_SKIP_WHITE
+ unsigned char val = *_read;
+
+ if (val)
+ {
+ if (val == max)
+ *_write = val;
+ else
+ *_write = saturation[ (int)*_write + *_read ];
+ }
+#else
+ *_write = saturation[ (int)*_write + *_read ];
+#endif
+ _write++;
+ _read++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+
+#define compose_pixel_full( a, b, n0, n1, n2, max ) \
+ { \
+ int d, half = max >> 1; \
+ \
+ \
+ d = (int)b.chroma[0] - a.chroma[0]; \
+ a.chroma[0] += (unsigned char)((n0*d + half)/max); \
+ \
+ d = (int)b.chroma[1] - a.chroma[1]; \
+ a.chroma[1] += (unsigned char)((n1*d + half)/max); \
+ \
+ d = (int)b.chroma[2] - a.chroma[2]; \
+ a.chroma[2] += (unsigned char)((n2*d + half)/max); \
+ }
+
+#define compose_pixel( a, b, n, max ) \
+ compose_pixel_full( a, b, n, n, n, max )
+
+
+#define extract555( pixel, color ) \
+ color.chroma[0] = (unsigned char)((pixel >> 10) & 0x1F); \
+ color.chroma[1] = (unsigned char)((pixel >> 5) & 0x1F); \
+ color.chroma[2] = (unsigned char)((pixel ) & 0x1F);
+
+
+#define extract565( pixel, color ) \
+ color.chroma[0] = (unsigned char)((pixel >> 11) & 0x1F); \
+ color.chroma[1] = (unsigned char)((pixel >> 5) & 0x3F); \
+ color.chroma[2] = (unsigned char)((pixel ) & 0x1F);
+
+
+#define inject555( color ) \
+ ( ( (unsigned short)color.chroma[0] << 10 ) | \
+ ( (unsigned short)color.chroma[1] << 5 ) | \
+ color.chroma[2] )
+
+
+#define inject565( color ) \
+ ( ( (unsigned short)color.chroma[0] << 11 ) | \
+ ( (unsigned short)color.chroma[1] << 5 ) | \
+ color.chroma[2] )
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_555 */
+/* */
+/**************************************************************************/
+
+#ifdef GRAY8
+ static
+ void blit_gray8_to_555( grBlitter* blit,
+ grColor color )
+ {
+ int y;
+ int sr = (color.chroma[0] << 8) & 0x7C00;
+ int sg = (color.chroma[1] << 2) & 0x03E0;
+ int sb = (color.chroma[2] ) & 0x001F;
+ unsigned char* read;
+ unsigned char* write;
+ long color2;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 2*blit->xwrite;
+
+ color2 = color.value;
+ extract565( color2, color );
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ unsigned short* pixel = (unsigned short*)_write;
+
+ if (val >= 254 )
+ {
+ pixel[0] = (short)color2;
+ }
+ else if ( val >= 2 )
+ {
+ /* compose gray value */
+ int pix = (int)*pixel;
+ int dr = pix & 0x7C00;
+ int dg = pix & 0x03E0;
+ int db = pix & 0x001F;
+
+ dr = pix & 0x7C00;
+ dr += ((sr-dr)*val) >> 8;
+ dr &= 0xF800;
+
+ dg = pix & 0x03E0;
+ dg += ((sg-dg)*val) >> 8;
+ dg &= 0x7E0;
+
+ db = pix & 0x001F;
+ db += ((sb-db)*val) >> 8;
+ db += 0x001F;
+
+ *pixel = (short)( dr | dg | db );
+ }
+ }
+ _write +=2;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+
+ }
+#endif /* GRAY8 */
+
+ static
+ void blit_gray_to_555( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ long color2;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 2*blit->xwrite;
+
+ /* convert color to R:G:B triplet */
+ color2 = color.value;
+ extract555( color2, color );
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ unsigned short* pixel = (unsigned short*)_write;
+
+ if (val == max)
+ {
+ pixel[0] = (short)color2;
+ }
+ else
+ {
+ /* compose gray value */
+ unsigned short pix16 = *pixel;
+ grColor pix;
+
+ extract555( pix16, pix );
+
+ compose_pixel( pix, color, val, max );
+ *pixel = (unsigned short)(inject555(pix));
+ }
+ }
+ _write += 2;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_565 */
+/* */
+/**************************************************************************/
+
+#ifdef GRAY8
+ static
+ void blit_gray8_to_565( grBlitter* blit,
+ grColor color )
+ {
+ int y;
+ int sr = (color.chroma[0] << 8) & 0xF800;
+ int sg = (color.chroma[1] << 2) & 0x07E0;
+ int sb = (color.chroma[2] ) & 0x001F;
+ unsigned char* read;
+ unsigned char* write;
+ long color2;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 2*blit->xwrite;
+
+ color2 = color.value;
+ extract565( color2, color );
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ unsigned short* pixel = (unsigned short*)_write;
+
+ if (val >= 254 )
+ {
+ pixel[0] = (short)color2;
+ }
+ else if ( val >= 2 )
+ {
+ /* compose gray value */
+ int pix = (int)*pixel;
+ int dr = pix & 0xF800;
+ int dg = pix & 0x07E0;
+ int db = pix & 0x001F;
+
+ dr = pix & 0xF800;
+ dr += ((sr-dr)*val) >> 8;
+ dr &= 0xF800;
+
+ dg = pix & 0x07E0;
+ dg += ((sg-dg)*val) >> 8;
+ dg &= 0x7E0;
+
+ db = pix & 0x001F;
+ db += ((sb-db)*val) >> 8;
+ db += 0x001F;
+
+ *pixel = (short)( dr | dg | db );
+ }
+ }
+ _write +=2;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+#endif
+
+ static
+ void blit_gray_to_565( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ long color2;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 2*blit->xwrite;
+
+ color2 = color.value;
+ extract565( color2, color );
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ unsigned short* pixel = (unsigned short*)_write;
+
+ if (val == max)
+ {
+ pixel[0] = (short)color2;
+ }
+ else
+ {
+ /* compose gray value */
+ unsigned short pix16 = *pixel;
+ grColor pix;
+
+ extract565( pix16, pix );
+
+ compose_pixel( pix, color, val, max );
+ *pixel = (short)inject565( pix );
+ }
+ }
+ _write +=2;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_24 */
+/* */
+/**************************************************************************/
+
+#ifdef GRAY8
+ static void
+ blit_gray8_to_24( grBlitter* blit,
+ grColor color )
+ {
+ int y;
+ int sr = color.chroma[0];
+ int sg = color.chroma[1];
+ int sb = color.chroma[2];
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ if (val >= 254)
+ {
+ _write[0] = (unsigned char)sr;
+ _write[1] = (unsigned char)sg;
+ _write[2] = (unsigned char)sb;
+ }
+ else if ( val >= 2 )
+ {
+ int dr = _write[0];
+ int dg = _write[1];
+ int db = _write[2];
+
+ dr += ((sr-dr)*val) >> 8;
+ dg += ((sg-dg)*val) >> 8;
+ db += ((sb-db)*val) >> 8;
+
+ _write[0] = (unsigned char)dr;
+ _write[1] = (unsigned char)dg,
+ _write[2] = (unsigned char)db;
+ }
+ }
+ _write += 3;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+#endif /* GRAY8 */
+
+
+ static
+ void blit_gray_to_24( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ if (val == max)
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel( pix, color, val, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 3;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_32 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_32( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 4*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ if (val == max)
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ _write[3] = color.chroma[3];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel( pix, color, val, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 4;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+ static
+ void blit_gray8_to_32( grBlitter* blit,
+ grColor color )
+ {
+ blit_gray_to_32( blit, color, 255 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_lcd_to_24 */
+/* */
+/**************************************************************************/
+
+#ifdef GRAY8
+ static void
+ blit_lcd8_to_24( grBlitter* blit,
+ grColor color )
+ {
+ int y;
+ int sr = color.chroma[0];
+ int sg = color.chroma[1];
+ int sb = color.chroma[2];
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + 3*blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ int val0, val1, val2;
+
+ val0 = _read[0];
+ val1 = _read[1];
+ val2 = _read[2];
+
+ if ( val0 | val1 | val2 )
+ {
+ if ( val0 == val1 &&
+ val0 == val2 &&
+ val0 == 255 )
+ {
+ _write[0] = (unsigned char)sr;
+ _write[1] = (unsigned char)sg;
+ _write[2] = (unsigned char)sb;
+ }
+ else
+ {
+ /* compose gray value */
+ int dr, dg, db;
+
+ dr = _write[0];
+ dr += (sr-dr)*val0 >> 8;
+
+ dg = _write[1];
+ dg += (sg-dg)*val1 >> 8;
+
+ db = _write[1];
+ db += (sb-db)*val2 >> 8;
+
+ _write[0] = dr;
+ _write[1] = dg;
+ _write[2] = db;
+ }
+ }
+ _write += 3;
+ _read += 3;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+#endif /* GRAY8 */
+
+ static void
+ blit_lcd_to_24( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + 3*blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ int val0, val1, val2;
+
+ val0 = _read[0];
+ val1 = _read[1];
+ val2 = _read[2];
+
+ if ( val0 | val1 | val2 )
+ {
+ if ( val0 == val1 &&
+ val0 == val2 &&
+ val0 == max )
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel_full( pix, color, val0, val1, val2, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 3;
+ _read += 3;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+#ifdef GRAY8
+ static void
+ blit_lcd28_to_24( grBlitter* blit,
+ grColor color )
+ {
+ int y;
+ int sr = color.chroma[0];
+ int sg = color.chroma[1];
+ int sb = color.chroma[2];
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + 3*blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ int val0, val1, val2;
+
+ val0 = _read[2];
+ val1 = _read[1];
+ val2 = _read[0];
+
+ if ( val0 | val1 | val2 )
+ {
+ if ( val0 == val1 &&
+ val0 == val2 &&
+ val0 == 255 )
+ {
+ _write[0] = (unsigned char)sr;
+ _write[1] = (unsigned char)sg;
+ _write[2] = (unsigned char)sb;
+ }
+ else
+ {
+ /* compose gray value */
+ int dr, dg, db;
+
+ dr = _write[0];
+ dr += (sr-dr)*val0 >> 8;
+
+ dg = _write[1];
+ dg += (sg-dg)*val1 >> 8;
+
+ db = _write[1];
+ db += (sb-db)*val2 >> 8;
+
+ _write[0] = dr;
+ _write[1] = dg;
+ _write[2] = db;
+ }
+ }
+ _write += 3;
+ _read += 3;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+#endif /* GRAY8 */
+
+ static void
+ blit_lcd2_to_24( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + 3*blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ int val0, val1, val2;
+
+ val0 = _read[2];
+ val1 = _read[1];
+ val2 = _read[0];
+
+ if ( val0 | val1 | val2 )
+ {
+ if ( val0 == val1 &&
+ val0 == val2 &&
+ val0 == max )
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel_full( pix, color, val0, val1, val2, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 3;
+ _read += 3;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_lcdv_to_24 */
+/* */
+/**************************************************************************/
+
+ static void
+ blit_lcdv_to_24( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ long line;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 3*blit->xwrite;
+ line = blit->read_line;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val0, val1, val2;
+
+ val0 = _read[0*line];
+ val1 = _read[1*line];
+ val2 = _read[2*line];
+
+ if ( val0 | val1 | val2 )
+ {
+ if ( val0 == val1 &&
+ val0 == val2 &&
+ val0 == max )
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel_full( pix, color, val0, val1, val2, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 3;
+ _read += 1;
+ x--;
+ }
+
+ read += 3*line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+ static void
+ blit_lcdv2_to_24( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ long line;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 3*blit->xwrite;
+ line = blit->read_line;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val0, val1, val2;
+
+ val0 = _read[2*line];
+ val1 = _read[1*line];
+ val2 = _read[0*line];
+
+ if ( val0 | val1 | val2 )
+ {
+ if ( val0 == val1 &&
+ val0 == val2 &&
+ val0 == max )
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel_full( pix, color, val0, val1, val2, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 3;
+ _read += 1;
+ x--;
+ }
+
+ read += 3*line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grBlitGlyphBitmap
+ *
+ * <Description>
+ * writes a given glyph bitmap to a target surface.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: position of left-most pixel of glyph image in surface
+ * y :: position of top-most pixel of glyph image in surface
+ * bitmap :: source glyph image
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ **********************************************************************/
+
+ typedef void (*grColorGlyphBlitter)( grBlitter* blit,
+ grColor color,
+ int max_gray );
+
+ static
+ const grColorGlyphBlitter gr_color_blitters[gr_pixel_mode_max] =
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ blit_gray_to_555,
+ blit_gray_to_565,
+ blit_gray_to_24,
+ blit_gray_to_32
+ };
+
+#ifdef GRAY8
+ typedef void (*grGray8GlyphBlitter)( grBlitter* blit,
+ grColor color );
+
+ static
+ const grGray8GlyphBlitter gr_gray8_blitters[gr_pixel_mode_max] =
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ blit_gray8_to_555,
+ blit_gray8_to_565,
+ blit_gray8_to_24,
+ blit_gray8_to_32
+ };
+#endif
+
+
+#include "gblblit.h"
+
+ static double gr_glyph_gamma = 1.0;
+
+ void grSetGlyphGamma( double gamma )
+ {
+ gr_glyph_gamma = gamma;
+ }
+
+
+ int
+ grBlitGlyphToBitmap( grBitmap* target,
+ grBitmap* glyph,
+ grPos x,
+ grPos y,
+ grColor color )
+ {
+ grBlitter blit;
+ grPixelMode mode;
+
+
+ /* check arguments */
+ if ( !target || !glyph )
+ {
+ grError = gr_err_bad_argument;
+ return -1;
+ }
+
+ /* short cut to alpha blender for certain glyph types
+ */
+ {
+ GBlenderSourceFormat src_format;
+ GBlenderTargetFormat dst_format;
+ int width, height;
+ GBlenderBlitRec gblit[1];
+ GBlenderPixel gcolor;
+ static GBlenderRec gblender[1];
+ static double gblender_gamma = -100.0;
+
+ if ( glyph->grays != 256 )
+ goto DefaultBlit;
+
+ switch ( glyph->mode )
+ {
+ case gr_pixel_mode_gray: src_format = GBLENDER_SOURCE_GRAY8; break;
+ case gr_pixel_mode_lcd: src_format = GBLENDER_SOURCE_HRGB; break;
+ case gr_pixel_mode_lcdv: src_format = GBLENDER_SOURCE_VRGB; break;
+ case gr_pixel_mode_lcd2: src_format = GBLENDER_SOURCE_HBGR; break;
+ case gr_pixel_mode_lcdv2: src_format = GBLENDER_SOURCE_VBGR; break;
+
+ default:
+ goto DefaultBlit;
+ }
+
+ width = glyph->width;
+ height = glyph->rows;
+
+ if ( glyph->mode == gr_pixel_mode_lcd ||
+ glyph->mode == gr_pixel_mode_lcd2 )
+ width /= 3;
+
+ if ( glyph->mode == gr_pixel_mode_lcdv ||
+ glyph->mode == gr_pixel_mode_lcdv2 )
+ height /= 3;
+
+ switch ( target->mode )
+ {
+ case gr_pixel_mode_rgb32: dst_format = GBLENDER_TARGET_RGB32; break;
+ case gr_pixel_mode_rgb24: dst_format = GBLENDER_TARGET_RGB24; break;
+ case gr_pixel_mode_rgb565: dst_format = GBLENDER_TARGET_RGB565; break;
+ default:
+ goto DefaultBlit;
+ }
+
+ /* initialize blender when needed, i.e. when gamma changes
+ */
+ if ( gblender_gamma != gr_glyph_gamma )
+ {
+ gblender_gamma = gr_glyph_gamma;
+ gblender_init( gblender, gblender_gamma );
+ }
+
+ if ( gblender_blit_init( gblit, gblender,
+ x, y,
+ src_format,
+ glyph->buffer,
+ glyph->pitch,
+ width,
+ height,
+ dst_format,
+ target->buffer,
+ target->pitch,
+ target->width,
+ target->rows ) < 0 )
+ {
+ /* nothing to do */
+ return 0;
+ }
+
+ gcolor = ((GBlenderPixel)color.chroma[0] << 16) |
+ ((GBlenderPixel)color.chroma[1] << 8 ) |
+ ((GBlenderPixel)color.chroma[2] ) ;
+
+ gblender_blit_run( gblit, gcolor );
+ return 1;
+ }
+
+ DefaultBlit:
+
+ /* set up blitter and compute clipping. Return immediately if needed */
+ blit.source = *glyph;
+ blit.target = *target;
+ mode = target->mode;
+
+ if ( compute_clips( &blit, x, y ) )
+ return 0;
+
+ switch ( glyph->mode )
+ {
+ case gr_pixel_mode_mono: /* handle monochrome bitmap blitting */
+ if ( mode <= gr_pixel_mode_none || mode >= gr_pixel_mode_max )
+ {
+ grError = gr_err_bad_source_depth;
+ return -1;
+ }
+
+ gr_mono_blitters[mode]( &blit, color );
+ break;
+
+ case gr_pixel_mode_gray:
+ if ( glyph->grays > 1 )
+ {
+ int target_grays = target->grays;
+ int source_grays = glyph->grays;
+ const byte* saturation;
+
+
+ if ( mode == gr_pixel_mode_gray && target_grays > 1 )
+ {
+ /* rendering into a gray target - use special composition */
+ /* routines.. */
+ if ( gr_last_saturation->count == target_grays )
+ saturation = gr_last_saturation->table;
+ else
+ {
+ saturation = grGetSaturation( target_grays );
+ if ( !saturation )
+ return -3;
+ }
+
+ if ( target_grays == source_grays )
+ blit_gray_to_gray_simple( &blit, saturation );
+ else
+ {
+ const byte* conversion;
+
+
+ if ( gr_last_conversion->target_grays == target_grays &&
+ gr_last_conversion->source_grays == source_grays )
+ conversion = gr_last_conversion->table;
+ else
+ {
+ conversion = grGetConversion( target_grays, source_grays );
+ if ( !conversion )
+ return -3;
+ }
+
+ blit_gray_to_gray( &blit, saturation, conversion );
+ }
+ }
+ else
+ {
+ /* rendering into a color target */
+ if ( mode <= gr_pixel_mode_gray ||
+ mode >= gr_pixel_mode_max )
+ {
+ grError = gr_err_bad_target_depth;
+ return -1;
+ }
+
+#ifdef GRAY8
+ if ( source_grays == 256 )
+ gr_gray8_blitters[mode]( &blit, color );
+ else
+#endif /* GRAY8 */
+ gr_color_blitters[mode]( &blit, color, source_grays - 1 );
+ }
+ }
+ break;
+
+ case gr_pixel_mode_lcd:
+ if ( mode == gr_pixel_mode_rgb24 )
+ {
+#ifdef GRAY8
+ if ( glyph->grays == 256 )
+ blit_lcd8_to_24( &blit, color );
+ else
+#endif
+ if ( glyph->grays > 1 )
+ blit_lcd_to_24( &blit, color, glyph->grays-1 );
+ }
+ break;
+
+
+ case gr_pixel_mode_lcdv:
+ if ( glyph->grays > 1 && mode == gr_pixel_mode_rgb24 )
+ {
+ blit_lcdv_to_24( &blit, color, glyph->grays-1 );
+ break;
+ }
+
+ case gr_pixel_mode_lcd2:
+ if ( mode == gr_pixel_mode_rgb24 )
+ {
+#ifdef GRAY8
+ if ( glyph->grays == 256 )
+ blit_lcd28_to_24( &blit, color );
+ else
+#endif
+ if ( glyph->grays > 1 )
+ blit_lcd2_to_24( &blit, color, glyph->grays-1 );
+ }
+ break;
+
+ case gr_pixel_mode_lcdv2:
+ if ( mode == gr_pixel_mode_rgb24 )
+ {
+ if ( glyph->grays > 1 )
+ blit_lcdv2_to_24( &blit, color, glyph->grays-1 );
+ }
+ break;
+
+ default:
+ /* we don't support the blitting of bitmaps of the following */
+ /* types : pal4, pal8, rgb555, rgb565, rgb24, rgb32 */
+ /* */
+ grError = gr_err_bad_source_depth;
+ return -2;
+ }
+
+ return 0;
+ }
+
+
+/* End */
diff --git a/kernel/kls_ttf/ftview/grblit.h b/kernel/kls_ttf/ftview/grblit.h
new file mode 100644
index 0000000..4d0b6e5
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grblit.h
@@ -0,0 +1,25 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-1999 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* blitter.h: Support for blitting of bitmaps with various depth. */
+/* */
+/****************************************************************************/
+
+#ifndef GRBLIT_H
+#define GRBLIT_H
+
+#include "grobjs.h"
+
+ int grBlitMono( grBitmap* target,
+ grBitmap* source,
+ int x_offset,
+ int y_offset,
+ grColor color );
+
+
+#endif /* GRBLIT_H */
+/* End */
diff --git a/kernel/kls_ttf/ftview/grconfig.h b/kernel/kls_ttf/ftview/grconfig.h
new file mode 100644
index 0000000..02d8f4d
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grconfig.h
@@ -0,0 +1,9 @@
+#ifndef GRCONFIG_H
+#define GRCONFIG_H
+
+#define GR_MAX_SATURATIONS 8
+#define GR_MAX_CONVERSIONS 16
+
+#define GR_MAX_DEVICES 8
+
+#endif /* GRCONFIG_H */
diff --git a/kernel/kls_ttf/ftview/grevents.h b/kernel/kls_ttf/ftview/grevents.h
new file mode 100644
index 0000000..36dd52d
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grevents.h
@@ -0,0 +1,117 @@
+#ifndef GREVENTS_H
+#define GREVENTS_H
+
+
+#define gr_event_none 0
+#define gr_event_wait 1
+#define gr_event_poll 2
+#define gr_event_flush 3
+
+#define gr_mouse_down 0x04
+#define gr_mouse_move 0x08
+#define gr_mouse_up 0x10
+#define gr_mouse_drag 0x20
+
+#define gr_key_down 0x40
+#define gr_key_up 0x80
+
+
+#define gr_event_mouse 0x3C
+#define gr_event_key 0xC0
+
+#define gr_event_type (gr_event_mouse | gr_event_key)
+
+
+ typedef enum grKey_
+ {
+ grKeyNone = 0,
+
+ grKeyF1,
+ grKeyF2,
+ grKeyF3,
+ grKeyF4,
+ grKeyF5,
+ grKeyF6,
+ grKeyF7,
+ grKeyF8,
+ grKeyF9,
+ grKeyF10,
+ grKeyF11,
+ grKeyF12,
+
+ grKeyLeft,
+ grKeyRight,
+ grKeyUp,
+ grKeyDown,
+
+ grKeyIns,
+ grKeyDel,
+ grKeyHome,
+ grKeyEnd,
+ grKeyPageUp,
+ grKeyPageDown,
+
+ grKeyEsc,
+ grKeyTab,
+ grKeyBackSpace,
+ grKeyReturn,
+
+ grKeyMax,
+ grKeyForceShort = 0x7FFF /* this forces the grKey to be stored */
+ /* on at least one short ! */
+
+ } grKey;
+
+#define grKEY(c) ((grKey)(c))
+
+#define grKeyAlt ((grKey)0x8000)
+#define grKeyCtrl ((grKey)0x4000)
+#define grKeyShift ((grKey)0x2000)
+
+#define grKeyModifiers ((grKey)0xE000)
+
+#define grKey0 grKEY('0')
+#define grKey1 grKEY('1')
+#define grKey2 grKEY('2')
+#define grKey3 grKEY('3')
+#define grKey4 grKEY('4')
+#define grKey5 grKEY('5')
+#define grKey6 grKEY('6')
+#define grKey7 grKEY('7')
+#define grKey8 grKEY('8')
+#define grKey9 grKEY('9')
+
+
+#define grKeyPlus grKEY('+')
+#define grKeyLess grKEY('-')
+#define grKeyEqual grKEY('=')
+#define grKeyMult grKEY('*')
+#define grKeyDollar grKEY('$')
+#define grKeySmaller grKEY('<')
+#define grKeyGreater grKEY('>')
+#define grKeyQuestion grKEY('?')
+#define grKeyComma grKEY(',')
+#define grKeyDot grKEY('.')
+#define grKeySemiColumn grKEY(';')
+#define grKeyColumn grKEY(':')
+#define grKeyDiv grKEY('/')
+#define grKeyExclam grKEY('!')
+#define grKeyPercent grKEY('%')
+#define grKeyLeftParen grKEY('(')
+#define grKeyRightParen grKEY('(')
+#define grKeyAt grKEY('@')
+#define grKeyUnder grKEY('_')
+
+
+ typedef struct grEvent_
+ {
+ int type;
+ grKey key;
+ int x, y;
+
+ } grEvent;
+
+
+
+#endif /* GREVENTS_H */
+
diff --git a/kernel/kls_ttf/ftview/grfont.cpp b/kernel/kls_ttf/ftview/grfont.cpp
new file mode 100644
index 0000000..b6dfa3b
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grfont.cpp
@@ -0,0 +1,373 @@
+
+#include "grfont.h"
+#include <string.h>
+
+ /* font characters */
+
+ const unsigned char font_8x8[2048] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
+ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
+ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C,
+ 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
+ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
+ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
+ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
+ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
+ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
+ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
+ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
+ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
+ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
+ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
+ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
+ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
+ 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC,
+ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
+ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
+ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
+ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
+ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
+ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
+ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
+ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
+ 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00,
+ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
+ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
+ 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
+ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
+ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
+ 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00,
+ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
+ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
+ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
+ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
+ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
+ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
+ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
+ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
+ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
+ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00,
+ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
+ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
+ 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00,
+ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
+ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
+ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
+ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
+ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
+ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
+ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
+ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
+ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
+ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
+ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
+ 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
+ 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00,
+ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
+ 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
+ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
+ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
+ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
+ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
+ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00,
+ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
+ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
+ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
+ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00,
+ 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
+ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
+ 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00,
+ 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00,
+ 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+ 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
+ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
+ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
+ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
+ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
+ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
+ 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C,
+ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00,
+ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38,
+ 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
+ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
+ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
+ 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
+ 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
+ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
+ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
+ 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
+ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
+ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
+ 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30,
+ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3,
+ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
+ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
+ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
+ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
+ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
+ 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
+ 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F,
+ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03,
+ 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00,
+ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
+ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
+ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+ 0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
+ 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
+ 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
+ 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
+ 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
+ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
+ 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
+ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
+ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
+ 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
+ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
+ 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
+ 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
+ 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00,
+ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
+ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
+ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
+ 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
+ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
+ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
+ 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
+ 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+
+ static
+ grBitmap gr_charcell =
+ {
+ 8, /* rows */
+ 8, /* width */
+ 1, /* pitch */
+ gr_pixel_mode_mono, /* mode */
+ 0, /* grays */
+ 0 /* buffer */
+ };
+
+ void grWriteCellChar( grBitmap* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color )
+ {
+ if (charcode < 0 || charcode > 255)
+ return;
+
+ gr_charcell.buffer = (unsigned char*)font_8x8 + 8 * charcode;
+ grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
+ }
+
+
+ void grWriteCellString( grBitmap* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color )
+ {
+ while (*string)
+ {
+ gr_charcell.buffer = (unsigned char *)font_8x8 +
+ 8 * (int)(unsigned char)*string++;
+ grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
+ x += 8;
+ }
+ }
+
+ static int gr_cursor_x = 0;
+ static int gr_cursor_y = 0;
+ static grBitmap* gr_text_bitmap = 0;
+ static int gr_margin_right = 0;
+ static int gr_margin_top = 0;
+
+
+ extern void grGotobitmap( grBitmap* bitmap )
+ {
+ gr_text_bitmap = bitmap;
+ }
+
+
+ extern void grSetMargin( int right, int top )
+ {
+ gr_margin_top = top << 3;
+ gr_margin_right = right << 3;
+ }
+
+
+ extern void grSetPixelMargin( int right, int top )
+ {
+ gr_margin_top = top;
+ gr_margin_right = right;
+ }
+
+
+ extern void grGotoxy ( int x, int y )
+ {
+ gr_cursor_x = x;
+ gr_cursor_y = y;
+ }
+
+
+ extern void grWrite ( const char* string )
+ {
+ if (string)
+ {
+ grColor color;
+
+ color.value = 127;
+ grWriteCellString( gr_text_bitmap,
+ gr_margin_right + (gr_cursor_x << 3),
+ gr_margin_top + (gr_cursor_y << 3),
+ string,
+ color );
+
+ gr_cursor_x += strlen(string);
+ }
+ }
+
+
+ extern void grLn( void )
+ {
+ gr_cursor_y ++;
+ gr_cursor_x = 0;
+ }
+
+
+ extern void grWriteln( const char* string )
+ {
+ grWrite( string );
+ grLn();
+ }
+
+
diff --git a/kernel/kls_ttf/ftview/grfont.h b/kernel/kls_ttf/ftview/grfont.h
new file mode 100644
index 0000000..47f226a
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grfont.h
@@ -0,0 +1,17 @@
+#ifndef GRFONT_H
+#define GRFONT_H
+
+#include "graph.h"
+
+ extern const unsigned char font_8x8[];
+
+ extern void grGotobitmap( grBitmap* bitmap );
+ extern void grSetMargin( int right, int top );
+ extern void grSetPixelMargin( int right, int top );
+ extern void grGotoxy ( int x, int y );
+
+ extern void grWrite ( const char* string );
+ extern void grWriteln( const char* string );
+ extern void grLn( void );
+
+#endif /* GRFONT_H */
diff --git a/kernel/kls_ttf/ftview/grobjs.cpp b/kernel/kls_ttf/ftview/grobjs.cpp
new file mode 100644
index 0000000..283c315
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grobjs.cpp
@@ -0,0 +1,213 @@
+#include "grobjs.h"
+#include <stdlib.h>
+#include <string.h>
+
+ int grError = 0;
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grRealloc
+ *
+ * <Description>
+ * Simple memory re-allocation.
+ *
+ * <Input>
+ * block :: original memory block address
+ * size :: new requested block size in bytes
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ unsigned char* grAlloc( long size )
+ {
+ unsigned char* p;
+
+ p = (unsigned char*)malloc(size);
+ if (!p && size > 0)
+ {
+ grError = gr_err_memory;
+ }
+
+ if (p)
+ memset( p, 0, size );
+
+ return p;
+ }
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grRealloc
+ *
+ * <Description>
+ * Simple memory re-allocation.
+ *
+ * <Input>
+ * block :: original memory block address
+ * size :: new requested block size in bytes
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ unsigned char* grRealloc( const unsigned char* block, long size )
+ {
+ unsigned char* p;
+
+ p = (unsigned char *)realloc( (void*)block, size );
+ if (!p && size > 0)
+ {
+ grError = gr_err_memory;
+ }
+ return p;
+ }
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grFree
+ *
+ * <Description>
+ * Simple memory release
+ *
+ * <Input>
+ * block :: target block
+ *
+ ********************************************************************/
+
+ void grFree( const void* block )
+ {
+ if (block)
+ free( (void *)block );
+ }
+
+
+
+ static
+ int check_mode( grPixelMode pixel_mode,
+ int num_grays )
+ {
+ if ( pixel_mode <= gr_pixel_mode_none ||
+ pixel_mode >= gr_pixel_mode_max )
+ goto Fail;
+
+ if ( pixel_mode != gr_pixel_mode_gray ||
+ ( num_grays >= 2 && num_grays <= 256 ) )
+ return 0;
+
+ Fail:
+ grError = gr_err_bad_argument;
+ return grError;
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewBitmap
+ *
+ * <Description>
+ * creates a new bitmap
+ *
+ * <Input>
+ * pixel_mode :: the target surface's pixel_mode
+ * num_grays :: number of grays levels for PAL8 pixel mode
+ * width :: width in pixels
+ * height :: height in pixels
+ *
+ * <Output>
+ * bit :: descriptor of the new bitmap
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ **********************************************************************/
+
+ extern int grNewBitmap( grPixelMode pixel_mode,
+ int num_grays,
+ int width,
+ int height,
+ grBitmap *bit )
+ {
+ int pitch;
+
+ /* check mode */
+ if (check_mode(pixel_mode,num_grays))
+ goto Fail;
+
+ /* check dimensions */
+ if (width < 0 || height < 0)
+ {
+ grError = gr_err_bad_argument;
+ goto Fail;
+ }
+
+ bit->width = width;
+ bit->rows = height;
+ bit->mode = pixel_mode;
+ bit->grays = num_grays;
+
+ pitch = width;
+
+ switch (pixel_mode)
+ {
+ case gr_pixel_mode_mono : pitch = (width+7) >> 3; break;
+ case gr_pixel_mode_pal4 : pitch = (width+3) >> 2; break;
+
+ case gr_pixel_mode_pal8 :
+ case gr_pixel_mode_gray : pitch = width; break;
+
+ case gr_pixel_mode_rgb555:
+ case gr_pixel_mode_rgb565: pitch = width*2; break;
+
+ case gr_pixel_mode_rgb24 : pitch = width*3; break;
+
+ case gr_pixel_mode_rgb32 : pitch = width*4; break;
+
+ default:
+ grError = gr_err_bad_target_depth;
+ return 0;
+ }
+
+ bit->pitch = pitch;
+ bit->buffer = grAlloc( (long)bit->pitch * bit->rows );
+ if (!bit->buffer) goto Fail;
+
+ return 0;
+
+ Fail:
+ return grError;
+ }
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grDoneBitmap
+ *
+ * <Description>
+ * destroys a bitmap
+ *
+ * <Input>
+ * bitmap :: handle to bitmap descriptor
+ *
+ * <Note>
+ * This function does NOT release the bitmap descriptor, only
+ * the pixel buffer.
+ *
+ **********************************************************************/
+
+ extern void grDoneBitmap( grBitmap* bit )
+ {
+ grFree( bit->buffer );
+ bit->buffer = 0;
+ }
+
+
+
diff --git a/kernel/kls_ttf/ftview/grobjs.h b/kernel/kls_ttf/ftview/grobjs.h
new file mode 100644
index 0000000..038ec54
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grobjs.h
@@ -0,0 +1,182 @@
+/***************************************************************************
+ *
+ * grobjs.h
+ *
+ * basic object classes defintions
+ *
+ * Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GROBJS_H
+#define GROBJS_H
+
+#include "graph.h"
+#include "grconfig.h"
+#include "grtypes.h"
+
+
+ typedef struct grBiColor_
+ {
+ grColor foreground;
+ grColor background;
+
+ int num_levels;
+ int max_levels;
+ grColor* levels;
+
+ } grBiColor;
+
+
+
+ /**********************************************************************
+ *
+ * Technical note : explaining how the blitter works.
+ *
+ * The blitter is used to "draw" a given source bitmap into
+ * a given target bitmap.
+ *
+ * The function called 'compute_clips' is used to compute clipping
+ * constraints. These lead us to compute two areas :
+ *
+ * - the read area : is the rectangle, within the source bitmap,
+ * which will be effectively "drawn" in the
+ * target bitmap.
+ *
+ * - the write area : is the rectangle, within the target bitmap,
+ * which will effectively "receive" the pixels
+ * from the read area
+ *
+ * Note that both areas have the same dimensions, but are
+ * located in distinct surfaces.
+ *
+ * These areas are computed by 'compute_clips' which is called
+ * by each blitting function.
+ *
+ * Note that we use the Y-downwards convention within the blitter
+ *
+ **********************************************************************/
+
+ typedef struct grBlitter_
+ {
+ int width; /* width in pixels of the areas */
+ int height; /* height in pixels of the areas */
+
+ int xread; /* x position of start point in read area */
+ int yread; /* y position of start point in read area */
+
+ int xwrite; /* x position of start point in write area */
+ int ywrite; /* y position of start point in write area */
+
+ int right_clip; /* amount of right clip */
+
+ unsigned char* read; /* top left corner of read area in source map */
+ unsigned char* write; /* top left corner of write area in target map */
+
+ int read_line; /* byte increment to go down one row in read area */
+ int write_line; /* byte increment to go down one row in write area */
+
+ grBitmap source; /* source bitmap descriptor */
+ grBitmap target; /* target bitmap descriptor */
+
+ } grBlitter;
+
+
+
+ typedef void (*grBlitterFunc)( grBlitter* blitter,
+ grColor color );
+
+ typedef void (*grSetTitleFunc)( grSurface* surface,
+ const char* title_string );
+
+ typedef void (*grRefreshRectFunc)( grSurface* surface,
+ int x,
+ int y,
+ int width,
+ int height );
+
+ typedef void (*grDoneSurfaceFunc)( grSurface* surface );
+
+ typedef int (*grListenEventFunc)( grSurface* surface,
+ int event_mode,
+ grEvent *event );
+
+
+
+ struct grSurface_
+ {
+ grDevice* device;
+ grBitmap bitmap;
+ grBool refresh;
+ grBool owner;
+
+ const byte* saturation; /* used for gray surfaces only */
+ grBlitterFunc blit_mono; /* 0 by default, set by grBlit.. */
+
+ grRefreshRectFunc refresh_rect;
+ grSetTitleFunc set_title;
+ grListenEventFunc listen_event;
+ grDoneSurfaceFunc done;
+ };
+
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grAlloc
+ *
+ * <Description>
+ * Simple memory allocation. The returned block is always zero-ed
+ *
+ * <Input>
+ * size :: size in bytes of the requested block
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ extern unsigned char* grAlloc( long size );
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grRealloc
+ *
+ * <Description>
+ * Simple memory re-allocation.
+ *
+ * <Input>
+ * block :: original memory block address
+ * size :: new requested block size in bytes
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ extern unsigned char* grRealloc( const unsigned char* block, long size );
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grFree
+ *
+ * <Description>
+ * Simple memory release
+ *
+ * <Input>
+ * block :: target block
+ *
+ ********************************************************************/
+
+ extern void grFree( const void* block );
+
+
+#endif /* GROBJS_H */
diff --git a/kernel/kls_ttf/ftview/grtypes.h b/kernel/kls_ttf/ftview/grtypes.h
new file mode 100644
index 0000000..7c39e2a
--- /dev/null
+++ b/kernel/kls_ttf/ftview/grtypes.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *
+ * grtypes.h
+ *
+ * basic type defintions
+ *
+ * Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRTYPES_H
+#define GRTYPES_H
+
+ typedef unsigned char byte;
+
+#if 0
+ typedef signed char uchar;
+
+ typedef unsigned long ulong;
+ typedef unsigned short ushort;
+ typedef unsigned int uint;
+#endif
+
+ typedef struct grDimension_
+ {
+ int x;
+ int y;
+
+ } grDimension;
+
+#define gr_err_ok 0
+#define gr_err_memory -1
+#define gr_err_bad_argument -2
+#define gr_err_bad_target_depth -3
+#define gr_err_bad_source_depth -4
+#define gr_err_saturation_overflow -5
+#define gr_err_conversion_overflow -6
+#define gr_err_invalid_device -7
+
+
+#ifdef GR_MAKE_OPTION_SINGLE_OBJECT
+#define GR_LOCAL_DECL static
+#define GR_LOCAL_FUNC static
+#else
+#define GR_LOCAL_DECL extern
+#define GR_LOCAL_FUNC /* void */
+#endif
+
+#endif /* GRTYPES_H */
diff --git a/kernel/kls_ttf/ttf2pnm.cpp b/kernel/kls_ttf/ttf2pnm.cpp
new file mode 100644
index 0000000..4571731
--- /dev/null
+++ b/kernel/kls_ttf/ttf2pnm.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-2000, 2003, 2004, 2005, 2006 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* */
+/* FTView - a simple font viewer. */
+/* */
+/* This is a new version using the MiGS graphics subsystem for */
+/* blitting and display. */
+/* */
+/* Press F1 when running this program to have a list of key-bindings */
+/* */
+/****************************************************************************/
+
+#include <freetype/config/ftheader.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ftcommon.h"
+#include <math.h>
+
+ /* the following header shouldn't be used in normal programs */
+#include FT_SYNTHESIS_H
+
+#define MAXPTSIZE 500 /* dtp */
+
+#ifdef CEIL
+#undef CEIL
+#endif
+#define CEIL( x ) ( ( (x) + 63 ) >> 6 )
+
+#define INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y ) \
+ do { \
+ start_x = 4; \
+ start_y = CEIL( size->metrics.height ); \
+ step_x = CEIL( size->metrics.max_advance ); \
+ step_y = CEIL( size->metrics.height ) + 4; \
+ \
+ x = start_x; \
+ y = start_y; \
+ } while ( 0 )
+
+#define X_TOO_LONG( x, size, bitmap) \
+ ( ( x ) + ( ( size )->metrics.max_advance >> 6 ) > bitmap->width )
+
+#define Y_TOO_LONG( y, size, bitmap) \
+ ( ( y ) >= bitmap->rows )
+
+grBitmap *bit;
+
+ static struct status_
+ {
+ FT_Encoding encoding;
+ int res;
+ int ptsize; /* current point size */
+
+ int font_index;
+ int Num; /* current first index */
+ int Fail;
+
+ } status = { FT_ENCODING_NONE, 72, 24, 0, 0, 0 };
+
+ static FTDemo_Handle* handle;
+
+ static FT_Error
+ Render_All( int num_indices,
+ int first_index )
+ {
+ int start_x, start_y, step_x, step_y, x, y;
+ int i;
+ FT_Size size;
+
+ error = FTDemo_Get_Size(handle, &size);
+
+ if ( error )
+ {
+ /* probably a non-existent bitmap font size */
+ return error;
+ }
+
+ INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y );
+
+ i = first_index;
+
+ while ( i < num_indices )
+ {
+ int gindex;
+
+ if ( handle->encoding == FT_ENCODING_NONE )
+ gindex = i;
+ else
+ gindex = FTDemo_Get_Index( handle, i );
+
+ error = FTDemo_Draw_Index( handle, bit, gindex, &x, &y );
+
+ if ( error )
+ status.Fail++;
+ else if ( X_TOO_LONG( x, size, bit ) )
+ {
+ x = start_x;
+ y += step_y;
+
+ if ( Y_TOO_LONG( y, size, bit ) )
+ break;
+ }
+
+ i++;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** REST OF THE APPLICATION/PROGRAM *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ event_font_change()
+ {
+ int num_indices;
+
+ status.font_index = 0;
+ status.Num = 0;
+
+ FTDemo_Set_Current_Font(handle, handle->fonts[status.font_index]);
+ FTDemo_Set_Current_Pointsize(handle, status.ptsize, status.res);
+ FTDemo_Update_Current_Flags(handle);
+
+ num_indices = handle->current_font->num_indices;
+
+ if(status.Num >= num_indices)
+ status.Num = num_indices - 1;
+ }
+
+
+ int
+ main( int argc,
+ char* argv[] )
+ {
+ if(argc != 3)
+ exit(1);
+
+ /* Initialize engine */
+ handle = FTDemo_New(status.encoding);
+
+ FTDemo_Install_Font(handle, argv[1]);
+
+ if(handle->num_fonts == 0)
+ PanicZ( "could not find/open any font file" );
+
+ bit = FTDemo_Display_New();
+
+ if(!bit)
+ PanicZ( "could not allocate display surface" );
+
+ status.Fail = 0;
+
+ event_font_change();
+
+ FTDemo_Update_Current_Flags(handle);
+
+ FTDemo_Display_Clear(bit);
+
+ Render_All(handle->current_font->num_indices, status.Num);
+
+ FILE *f = fopen(argv[2], "wb");
+
+ fprintf(f, "P6\n%d %d\n255\n", bit->width, bit->rows);
+ fwrite(bit->buffer, bit->width * bit->rows * 3, 1, f);
+
+ fclose(f);
+
+ FTDemo_Display_Done(bit);
+ FTDemo_Done(handle);
+
+ return 0;
+ }
diff --git a/kernel/kls_utah/Makefile.am b/kernel/kls_utah/Makefile.am
new file mode 100644
index 0000000..965b4cb
--- /dev/null
+++ b/kernel/kls_utah/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-utah2ppm
+
+pkglib_LTLIBRARIES = libkls_utah.la
+
+libkls_utah_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_utah_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_utah_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_UTAH -DNETPBM_S=\"${bindir}/ksquirrel-libs-utah2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-utah2ppm.in \ No newline at end of file
diff --git a/kernel/kls_utah/fmt_codec_pnm.cpp b/kernel/kls_utah/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_utah/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_utah/fmt_codec_pnm_defs.h b/kernel/kls_utah/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_utah/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_utah/ksquirrel-libs-utah2ppm.in b/kernel/kls_utah/ksquirrel-libs-utah2ppm.in
new file mode 100644
index 0000000..1d77d7a
--- /dev/null
+++ b/kernel/kls_utah/ksquirrel-libs-utah2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@UTAHTOPNM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_wal/Makefile.am b/kernel/kls_wal/Makefile.am
new file mode 100644
index 0000000..388c52b
--- /dev/null
+++ b/kernel/kls_wal/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_wal.la
+
+libkls_wal_la_SOURCES = fmt_codec_wal.cpp fmt_codec_wal_defs.h q2pal.h
+
+libkls_wal_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_wal_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_wal/fmt_codec_wal.cpp b/kernel/kls_wal/fmt_codec_wal.cpp
new file mode 100644
index 0000000..a5b46d5
--- /dev/null
+++ b/kernel/kls_wal/fmt_codec_wal.cpp
@@ -0,0 +1,172 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_wal_defs.h"
+#include "fmt_codec_wal.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "q2pal.h"
+
+#include "../xpm/codec_wal.xpm"
+
+/*
+ *
+ * Quake2 WAL texture
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.2.0";
+ o->name = "Quake2 texture";
+ o->filter = "*.wal ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-wal";
+ o->pixmap = codec_wal;
+ o->readable = true;
+ o->canbemultiple = true;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ bits = NULL;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage == 4)
+ return SQE_NOTOK;
+
+ if(!currentImage)
+ {
+ if(!frs.readK(&wal, sizeof(wal_header)))
+ return SQE_R_BADFILE;
+
+ neww = wal.width;
+ newh = wal.height;
+
+ fmt_metaentry mt;
+
+ mt.group = "Quake2 texture name";
+ mt.data = wal.name;
+ addmeta(mt);
+
+ mt.group = "Quake2 next texture name";
+ mt.data = wal.next_name;
+ addmeta(mt);
+ }
+ else
+ {
+ neww /= 2;
+ newh /= 2;
+ }
+
+ bits = (u8 *)realloc(bits, neww * newh);
+
+ if(!bits)
+ return SQE_R_NOMEMORY;
+
+ fmt_image image;
+
+ frs.seekg(wal.offset[currentImage], ios::beg);
+
+ if(!frs.good())
+ return SQE_R_BADFILE;
+
+ image.w = neww;
+ image.h = newh;
+ image.bpp = 8;
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(8);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ if(!frs.readK(bits, im->w))
+ return SQE_R_BADFILE;
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ scan[i].r = q2pal[bits[i] * 3];
+ scan[i].g = q2pal[bits[i] * 3 + 1];
+ scan[i].b = q2pal[bits[i] * 3 + 2];
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ if(bits) free(bits);
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_wal/fmt_codec_wal_defs.h b/kernel/kls_wal/fmt_codec_wal_defs.h
new file mode 100644
index 0000000..1e8210f
--- /dev/null
+++ b/kernel/kls_wal/fmt_codec_wal_defs.h
@@ -0,0 +1,42 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_wal
+#define KSQUIRREL_CODEC_DEFS_wal
+
+typedef struct
+{
+ s8 name[32]; /* name of the texture */
+
+ u32 width; /* width (in pixels) of the largest mipmap level */
+ u32 height; /* height (in pixels) of the largest mipmap level */
+
+ s32 offset[4]; /* byte offset of the start of each of the 4 mipmap levels */
+
+ s8 next_name[32]; /* name of the next texture in the animation */
+
+ u32 flags;
+ u32 contents;
+ u32 value;
+
+}wal_header;
+
+#endif
diff --git a/kernel/kls_wal/q2pal.h b/kernel/kls_wal/q2pal.h
new file mode 100644
index 0000000..39530e5
--- /dev/null
+++ b/kernel/kls_wal/q2pal.h
@@ -0,0 +1,266 @@
+#ifndef Q2PAL_H
+#define Q2PAL_H
+
+/* Quake2 pallette taken from DevIL library (http://imagelib.org) */
+
+static const s8 q2pal[768] =
+{
+ 0, 0, 0,
+ 15, 15, 15,
+ 31, 31, 31,
+ 47, 47, 47,
+ 63, 63, 63,
+ 75, 75, 75,
+ 91, 91, 91,
+ 107, 107, 107,
+ 123, 123, 123,
+ 139, 139, 139,
+ 155, 155, 155,
+ 171, 171, 171,
+ 187, 187, 187,
+ 203, 203, 203,
+ 219, 219, 219,
+ 235, 235, 235,
+ 99, 75, 35,
+ 91, 67, 31,
+ 83, 63, 31,
+ 79, 59, 27,
+ 71, 55, 27,
+ 63, 47, 23,
+ 59, 43, 23,
+ 51, 39, 19,
+ 47, 35, 19,
+ 43, 31, 19,
+ 39, 27, 15,
+ 35, 23, 15,
+ 27, 19, 11,
+ 23, 15, 11,
+ 19, 15, 7,
+ 15, 11, 7,
+ 95, 95, 111,
+ 91, 91, 103,
+ 91, 83, 95,
+ 87, 79, 91,
+ 83, 75, 83,
+ 79, 71, 75,
+ 71, 63, 67,
+ 63, 59, 59,
+ 59, 55, 55,
+ 51, 47, 47,
+ 47, 43, 43,
+ 39, 39, 39,
+ 35, 35, 35,
+ 27, 27, 27,
+ 23, 23, 23,
+ 19, 19, 19,
+ 143, 119, 83,
+ 123, 99, 67,
+ 115, 91, 59,
+ 103, 79, 47,
+ 207, 151, 75,
+ 167, 123, 59,
+ 139, 103, 47,
+ 111, 83, 39,
+ 235, 159, 39,
+ 203, 139, 35,
+ 175, 119, 31,
+ 147, 99, 27,
+ 119, 79, 23,
+ 91, 59, 15,
+ 63, 39, 11,
+ 35, 23, 7,
+ 167, 59, 43,
+ 159, 47, 35,
+ 151, 43, 27,
+ 139, 39, 19,
+ 127, 31, 15,
+ 115, 23, 11,
+ 103, 23, 7,
+ 87, 19, 0,
+ 75, 15, 0,
+ 67, 15, 0,
+ 59, 15, 0,
+ 51, 11, 0,
+ 43, 11, 0,
+ 35, 11, 0,
+ 27, 7, 0,
+ 19, 7, 0,
+ 123, 95, 75,
+ 115, 87, 67,
+ 107, 83, 63,
+ 103, 79, 59,
+ 95, 71, 55,
+ 87, 67, 51,
+ 83, 63, 47,
+ 75, 55, 43,
+ 67, 51, 39,
+ 63, 47, 35,
+ 55, 39, 27,
+ 47, 35, 23,
+ 39, 27, 19,
+ 31, 23, 15,
+ 23, 15, 11,
+ 15, 11, 7,
+ 111, 59, 23,
+ 95, 55, 23,
+ 83, 47, 23,
+ 67, 43, 23,
+ 55, 35, 19,
+ 39, 27, 15,
+ 27, 19, 11,
+ 15, 11, 7,
+ 179, 91, 79,
+ 191, 123, 111,
+ 203, 155, 147,
+ 215, 187, 183,
+ 203, 215, 223,
+ 179, 199, 211,
+ 159, 183, 195,
+ 135, 167, 183,
+ 115, 151, 167,
+ 91, 135, 155,
+ 71, 119, 139,
+ 47, 103, 127,
+ 23, 83, 111,
+ 19, 75, 103,
+ 15, 67, 91,
+ 11, 63, 83,
+ 7, 55, 75,
+ 7, 47, 63,
+ 7, 39, 51,
+ 0, 31, 43,
+ 0, 23, 31,
+ 0, 15, 19,
+ 0, 7, 11,
+ 0, 0, 0,
+ 139, 87, 87,
+ 131, 79, 79,
+ 123, 71, 71,
+ 115, 67, 67,
+ 107, 59, 59,
+ 99, 51, 51,
+ 91, 47, 47,
+ 87, 43, 43,
+ 75, 35, 35,
+ 63, 31, 31,
+ 51, 27, 27,
+ 43, 19, 19,
+ 31, 15, 15,
+ 19, 11, 11,
+ 11, 7, 7,
+ 0, 0, 0,
+ 151, 159, 123,
+ 143, 151, 115,
+ 135, 139, 107,
+ 127, 131, 99,
+ 119, 123, 95,
+ 115, 115, 87,
+ 107, 107, 79,
+ 99, 99, 71,
+ 91, 91, 67,
+ 79, 79, 59,
+ 67, 67, 51,
+ 55, 55, 43,
+ 47, 47, 35,
+ 35, 35, 27,
+ 23, 23, 19,
+ 15, 15, 11,
+ 159, 75, 63,
+ 147, 67, 55,
+ 139, 59, 47,
+ 127, 55, 39,
+ 119, 47, 35,
+ 107, 43, 27,
+ 99, 35, 23,
+ 87, 31, 19,
+ 79, 27, 15,
+ 67, 23, 11,
+ 55, 19, 11,
+ 43, 15, 7,
+ 31, 11, 7,
+ 23, 7, 0,
+ 11, 0, 0,
+ 0, 0, 0,
+ 119, 123, 207,
+ 111, 115, 195,
+ 103, 107, 183,
+ 99, 99, 167,
+ 91, 91, 155,
+ 83, 87, 143,
+ 75, 79, 127,
+ 71, 71, 115,
+ 63, 63, 103,
+ 55, 55, 87,
+ 47, 47, 75,
+ 39, 39, 63,
+ 35, 31, 47,
+ 27, 23, 35,
+ 19, 15, 23,
+ 11, 7, 7,
+ 155, 171, 123,
+ 143, 159, 111,
+ 135, 151, 99,
+ 123, 139, 87,
+ 115, 131, 75,
+ 103, 119, 67,
+ 95, 111, 59,
+ 87, 103, 51,
+ 75, 91, 39,
+ 63, 79, 27,
+ 55, 67, 19,
+ 47, 59, 11,
+ 35, 47, 7,
+ 27, 35, 0,
+ 19, 23, 0,
+ 11, 15, 0,
+ 0, 255, 0,
+ 35, 231, 15,
+ 63, 211, 27,
+ 83, 187, 39,
+ 95, 167, 47,
+ 95, 143, 51,
+ 95, 123, 51,
+ 255, 255, 255,
+ 255, 255, 211,
+ 255, 255, 167,
+ 255, 255, 127,
+ 255, 255, 83,
+ 255, 255, 39,
+ 255, 235, 31,
+ 255, 215, 23,
+ 255, 191, 15,
+ 255, 171, 7,
+ 255, 147, 0,
+ 239, 127, 0,
+ 227, 107, 0,
+ 211, 87, 0,
+ 199, 71, 0,
+ 183, 59, 0,
+ 171, 43, 0,
+ 155, 31, 0,
+ 143, 23, 0,
+ 127, 15, 0,
+ 115, 7, 0,
+ 95, 0, 0,
+ 71, 0, 0,
+ 47, 0, 0,
+ 27, 0, 0,
+ 239, 0, 0,
+ 55, 55, 255,
+ 255, 0, 0,
+ 0, 0, 255,
+ 43, 43, 35,
+ 27, 27, 23,
+ 19, 19, 15,
+ 235, 151, 127,
+ 195, 115, 83,
+ 159, 87, 51,
+ 123, 63, 27,
+ 235, 211, 199,
+ 199, 171, 155,
+ 167, 139, 119,
+ 135, 107, 87,
+ 159, 91, 83
+};
+
+#endif
diff --git a/kernel/kls_wbmp/Makefile.am b/kernel/kls_wbmp/Makefile.am
new file mode 100644
index 0000000..9c2d093
--- /dev/null
+++ b/kernel/kls_wbmp/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_wbmp.la
+
+libkls_wbmp_la_SOURCES = fmt_codec_wbmp.cpp fmt_codec_wbmp_defs.h
+
+libkls_wbmp_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_wbmp_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_wbmp/fmt_codec_wbmp.cpp b/kernel/kls_wbmp/fmt_codec_wbmp.cpp
new file mode 100644
index 0000000..f69dab6
--- /dev/null
+++ b/kernel/kls_wbmp/fmt_codec_wbmp.cpp
@@ -0,0 +1,278 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+/*
+ * The Wireless Application Protocol Bitmap Format (WBMP) is designed for use
+ * with applications that operate over wireless communication networks.
+ * The WBMP format is commonly used in mobile phones (WAP phones) and enables
+ * graphical information to be sent to the handset.
+ * This format is very simple and allows to store image only in 1-bit
+ * format (black and white).
+ */
+
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_wbmp_defs.h"
+#include "fmt_codec_wbmp.h"
+
+#include "../xpm/codec_wbmp.xpm"
+
+/*
+ *
+ * WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap
+ * Specification of the WBMP format can be found in the
+ * SPEC-WAESpec-19990524.pdf
+ *
+ * You can download the WAP specification on: http://www.wapforum.com/
+ *
+ */
+
+static const RGB mono[2] = { RGB(255,255,255), RGB(0,0,0) };
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.9.0";
+ o->name = "Wireless Application Protocol Bitmap";
+ o->filter = "*.wbmp ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-wbmp";
+ o->pixmap = codec_wbmp;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ wbmp.bitmap = NULL;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ u8 type;
+
+ frs.readK(&type, sizeof(u8));
+
+ wbmp.type = type;
+
+ if(wbmp.type != 0)
+ return SQE_R_BADFILE;
+
+ if(skipheader(frs))
+ return SQE_R_BADFILE;
+
+ wbmp.width = getmbi(frs);
+
+ if(wbmp.width == -1)
+ return SQE_R_BADFILE;
+
+ wbmp.height = getmbi(frs);
+
+ if(wbmp.height == -1)
+ return SQE_R_BADFILE;
+
+ image.w = wbmp.width;
+ image.h = wbmp.height;
+ image.bpp = 1;
+
+ wbmp.bitmap = new s32 [wbmp.width * wbmp.height];
+
+ if(!wbmp.bitmap)
+ return SQE_R_NOMEMORY;
+
+ s32 row, col, byte, pel, pos;
+ u8 b;
+
+ pos = 0;
+
+ for(row = 0;row < wbmp.height;row++)
+ {
+ for(col = 0;col < wbmp.width;)
+ {
+ if(!frs.readK(&b, sizeof(u8)))
+ return SQE_R_BADFILE;
+
+ byte = b;
+
+ for(pel = 7;pel >= 0;pel--)
+ {
+ if(col++ < wbmp.width)
+ {
+ if(byte & 1 << pel)
+ wbmp.bitmap[pos] = WBMP_WHITE;
+ else
+ wbmp.bitmap[pos] = WBMP_BLACK;
+
+ pos++;
+ }
+ }
+ }
+ }
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(1);
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ for(s32 i = 0;i < im->w;i++)
+ memcpy(scan+i, mono + (wbmp.bitmap[line * im->w + i]), sizeof(RGB));
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ delete [] wbmp.bitmap;
+ wbmp.bitmap = NULL;
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+/*
+ *
+ * These functions were taken from Wbmp program by Johan Van den Brande
+ *
+ * (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
+ *
+ */
+
+s32 fmt_codec::getmbi(ifstreamK &f)
+{
+ s32 mbi = 0;
+ s8 i;
+
+ do
+ {
+ f.readK(&i, sizeof(s8));
+
+ if(i < 0)
+ return -1;
+
+ mbi = (mbi << 7) | (i & 0x7f);
+
+ }while(i & 0x80);
+
+ return mbi;
+}
+
+s32 fmt_codec::putmbi(s32 i, ofstreamK &f)
+{
+ s32 cnt, l, accu;
+ u8 s;
+
+ /* Get number of septets */
+ cnt = 0;
+ accu = 0;
+
+ while(accu != i)
+ accu += i & 0x7f << 7*cnt++;
+
+ /* Produce the multibyte output */
+ for(l = cnt-1;l > 0;l--)
+ {
+ s = 0x80 | (i & 0x7f << 7*l ) >> 7*l;
+ f.writeK(&s, sizeof(s8));
+ }
+
+ s = i & 0x7f;
+
+ f.writeK(&s, sizeof(u8));
+
+ return 0;
+}
+
+s32 fmt_codec::skipheader(ifstreamK &f)
+{
+ s8 i;
+ bool b;
+
+ do
+ {
+ b = f.readK(&i, sizeof(s8));
+
+ if(!b)
+ return -1;
+
+ if(i < 0)
+ return -1;
+
+ }while(i & 0x80);
+
+ return 0;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_wbmp/fmt_codec_wbmp_defs.h b/kernel/kls_wbmp/fmt_codec_wbmp_defs.h
new file mode 100644
index 0000000..b774933
--- /dev/null
+++ b/kernel/kls_wbmp/fmt_codec_wbmp_defs.h
@@ -0,0 +1,37 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_wbmp
+#define KSQUIRREL_READ_IMAGE_wbmp
+
+struct Wbmp
+{
+ s32 type; /* type of the wbmp */
+ s32 width; /* width of the image */
+ s32 height; /* height of the image */
+ s32 *bitmap; /* pointer to data: 0 = WHITE , 1 = BLACK */
+
+}PACKED;
+
+#define WBMP_WHITE 0
+#define WBMP_BLACK 1
+
+#endif
diff --git a/kernel/kls_wmf/Makefile.am b/kernel/kls_wmf/Makefile.am
new file mode 100644
index 0000000..be71d57
--- /dev/null
+++ b/kernel/kls_wmf/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include @SQ_WMF_CFLAGS@
+
+pkglib_LTLIBRARIES = libkls_wmf.la
+
+libkls_wmf_la_SOURCES = fmt_codec_wmf.cpp wmf2mem.cpp fmt_codec_wmf_defs.h
+
+libkls_wmf_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_wmf_la_LIBADD = @SQ_WMF_LDFLAGS@ ${SQ_LOCAL_RPATH} \ No newline at end of file
diff --git a/kernel/kls_wmf/fmt_codec_wmf.cpp b/kernel/kls_wmf/fmt_codec_wmf.cpp
new file mode 100644
index 0000000..ec5045d
--- /dev/null
+++ b/kernel/kls_wmf/fmt_codec_wmf.cpp
@@ -0,0 +1,150 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_wmf_defs.h"
+#include "fmt_codec_wmf.h"
+
+#include "../xpm/codec_wmf.xpm"
+
+/*
+ *
+ * Microsoft Windows Metafile Format (WMF) files are used to store both
+ * vector and bitmap-format graphical data in memory or in disk files.
+ * The vector data stored in WMF files is described as Microsoft Windows
+ * Graphics Device Interface (GDI) commands. In the Window environment
+ * these commands are interpreted and played back on an output device
+ * using the Windows API PlayMetaFile() function. Bitmap data stored in
+ * a WMF file may be stored in the form of a Microsoft Device Dependent
+ * Bitmap (DDB), or Device Independent Bitmap (DIB).
+ *
+ */
+
+extern int call(int, char **, unsigned char **, int *, int *);
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.9.0";
+ o->name = "Windows Metafile";
+ o->filter = "*.wmf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-wmf";
+ o->pixmap = codec_wmf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ frs.close();
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ const char * argv[] =
+ {
+ "wmf2gd",
+ file.c_str()
+ };
+
+ buf = NULL;
+
+ call(2, (char **)argv, &buf, &w, &h);
+
+ if(!buf)
+ return SQE_R_NOMEMORY;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ image.bpp = 32;
+ image.w = w;
+ image.h = h;
+ image.compression = "-";
+ image.colorspace = "Vectorized RGB";
+
+ finfo.image.push_back(image);
+
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ line++;
+
+ memcpy(scan, buf + line * im->w * sizeof(RGBA), im->w * sizeof(RGBA));
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ delete [] buf;
+ buf = NULL;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_wmf/fmt_codec_wmf_defs.h b/kernel/kls_wmf/fmt_codec_wmf_defs.h
new file mode 100644
index 0000000..5167e0a
--- /dev/null
+++ b/kernel/kls_wmf/fmt_codec_wmf_defs.h
@@ -0,0 +1,25 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_wmf
+#define KSQUIRREL_READ_IMAGE_wmf
+
+#endif
diff --git a/kernel/kls_wmf/wmf2mem.cpp b/kernel/kls_wmf/wmf2mem.cpp
new file mode 100644
index 0000000..ed644e1
--- /dev/null
+++ b/kernel/kls_wmf/wmf2mem.cpp
@@ -0,0 +1,361 @@
+/* libwmf (convert/wmf2gd.c): library for wmf conversion
+ Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources
+
+ The libwmf Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The libwmf Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the libwmf Library; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cctype>
+#include <cmath>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_defs.h"
+
+#include <libwmf/fund.h>
+#include <libwmf/types.h>
+#include <libwmf/api.h>
+#include <libwmf/ipa.h>
+#include <libwmf/font.h>
+#include <libwmf/color.h>
+#include <libwmf/macro.h>
+
+#include <libwmf/gd.h>
+
+typedef struct
+{ int argc;
+ char** argv;
+
+ char* wmf_filename;
+ char* gd_filename;
+
+ wmf_gd_t options;
+
+ unsigned int max_width;
+ unsigned int max_height;
+
+ unsigned long max_flags;
+
+} PlotData;
+
+#define WMF2GD_MAXPECT (1 << 0)
+#define WMF2GD_MAXSIZE (1 << 1)
+
+int wmf2gd_draw (PlotData*, unsigned char **buf, int *w, int *h);
+
+void wmf2gd_init (PlotData*,int,char**);
+int wmf2gd_args (PlotData*);
+int wmf2gd_file (PlotData*, unsigned char **buf, int *w, int *h);
+
+int call(int argc,char** argv, unsigned char **buf, int *w, int *h);
+
+int explicit_wmf_error(wmf_error_t);
+
+int wmf2gd_draw (PlotData* pdata, unsigned char **buf, int *www, int *hhh)
+{
+ int status = 0;
+
+ float wmf_width;
+ float wmf_height;
+
+ float ratio_wmf;
+ float ratio_bounds;
+
+ unsigned int disp_width = 0;
+ unsigned int disp_height = 0;
+
+ unsigned long flags;
+ unsigned long max_flags;
+
+ wmf_error_t err;
+
+ wmf_gd_t* ddata = 0;
+
+ wmfAPI* API = 0;
+
+ wmfAPI_Options api_options;
+
+ flags = 0;
+
+ flags |= WMF_OPT_FUNCTION;
+ api_options.function = wmf_gd_function;
+
+ flags |= WMF_OPT_ARGS;
+ api_options.argc = pdata->argc;
+ api_options.argv = pdata->argv;
+#ifndef DEBUG
+ flags |= WMF_OPT_IGNORE_NONFATAL;
+#endif
+ err = wmf_api_create (&API,flags,&api_options);
+ status = explicit_wmf_error (err);
+
+ if (status)
+ { if (API) wmf_api_destroy (API);
+ return (status);
+ }
+
+ ddata = WMF_GD_GetData (API);
+
+ err = wmf_file_open(API, pdata->wmf_filename);
+ status = explicit_wmf_error (err);
+
+ if (status)
+ {
+ wmf_api_destroy (API);
+ return (status);
+ }
+
+ err = wmf_scan (API, 0, &(pdata->options.bbox));
+ status = explicit_wmf_error (err);
+
+ if (status)
+ {
+ wmf_api_destroy (API);
+ return (status);
+ }
+
+/* Okay, got this far, everything seems cool.
+ */
+ ddata->type = pdata->options.type;
+
+ ddata->flags |= WMF_GD_OUTPUT_MEMORY;
+ ddata->file = pdata->options.file;
+
+ ddata->bbox = pdata->options.bbox;
+
+ wmf_display_size (API, &disp_width, &disp_height, 72, 72);
+
+ wmf_width = (float) disp_width;
+ wmf_height = (float) disp_height;
+
+ if ((wmf_width <= 0) || (wmf_height <= 0))
+ {
+ status = 1;
+ wmf_api_destroy (API);
+ return (status);
+ }
+
+ max_flags = pdata->max_flags;
+
+ if ((wmf_width > (float) pdata->max_width ) || (wmf_height > (float) pdata->max_height))
+ if (max_flags == 0)
+ max_flags = WMF2GD_MAXPECT;
+
+ if (max_flags == WMF2GD_MAXPECT) /* scale the image */
+ { ratio_wmf = wmf_height / wmf_width;
+ ratio_bounds = (float) pdata->max_height / (float) pdata->max_width;
+
+ if (ratio_wmf > ratio_bounds)
+ { ddata->height = pdata->max_height;
+ ddata->width = (unsigned int) ((float) ddata->height / ratio_wmf);
+ }
+ else
+ { ddata->width = pdata->max_width;
+ ddata->height = (unsigned int) ((float) ddata->width * ratio_wmf);
+ }
+ }
+ else if (max_flags == WMF2GD_MAXSIZE) /* bizarre option, really */
+ { ddata->width = pdata->max_width;
+ ddata->height = pdata->max_height;
+ }
+ else
+ { ddata->width = (unsigned int) ceil ((double) wmf_width );
+ ddata->height = (unsigned int) ceil ((double) wmf_height);
+ }
+
+ if (status == 0)
+ {
+ err = wmf_play(API, 0, &(pdata->options.bbox));
+ status = explicit_wmf_error (err);
+ }
+
+ wmf_api_destroy(API);
+
+ int *p = wmf_gd_image_pixels(ddata->gd_image);
+ unsigned int w, h;
+
+ unsigned int pixel;
+ unsigned char r, g, b, a;
+
+ *buf = new u8 [ddata->height * ddata->width * sizeof(RGBA)];
+
+ if(!*buf)
+ return 1;
+
+ unsigned char *pss = *buf;
+
+ for (h = 0; h < ddata->height; h++)
+ for (w = 0; w < ddata->width; w++)
+ {
+ pixel = (unsigned int) (*p++);
+
+ b = (unsigned char) (pixel & 0xff);
+ pixel >>= 8;
+ g = (unsigned char) (pixel & 0xff);
+ pixel >>= 8;
+ r = (unsigned char) (pixel & 0xff);
+ pixel >>= 7;
+ a = (unsigned char) (pixel & 0xfe);
+ a ^= 0xff;
+
+ *pss++ = r;
+ *pss++ = g;
+ *pss++ = b;
+ *pss++ = a;
+ }
+
+ *www = ddata->width;
+ *hhh = ddata->height;
+
+ free(ddata->gd_image);
+
+ if(ddata->memory)
+ free(ddata->memory);
+
+ return status;
+}
+
+void wmf2gd_init(PlotData *pdata, int argc, char **argv)
+{
+ pdata->argc = argc;
+ pdata->argv = argv;
+
+ pdata->wmf_filename = 0;
+ pdata->gd_filename = 0;
+
+ pdata->options.type = wmf_gd_png;
+
+ pdata->options.file = 0;
+
+ pdata->options.width = 0;
+ pdata->options.height = 0;
+
+ pdata->options.flags = 0;
+
+ pdata->max_width = 768;
+ pdata->max_height = 512;
+
+ pdata->max_flags = 0;
+}
+
+int wmf2gd_args (PlotData* pdata)
+{
+ int status = 0;
+ int arg = 0;
+
+ int argc = pdata->argc;
+ char** argv = pdata->argv;
+
+ while ((++arg) < argc)
+ {
+ if (strcmp (argv[arg],"-o") == 0)
+ { if ((++arg) < argc)
+ { pdata->gd_filename = argv[arg];
+ continue;
+ }
+ fprintf (stderr,"usage: `wmf2gd -o <file.gd> <file.wmf>'.\n");
+ fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
+ status = arg;
+ break;
+ }
+
+ if (argv[arg][0] != '-')
+ { pdata->wmf_filename = argv[arg];
+ continue;
+ }
+
+ fprintf (stderr,"option `%s' not recognized.\n",argv[arg]);
+ fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
+ status = arg;
+
+ break;
+ }
+
+ if (status == 0)
+ { if(pdata->wmf_filename == 0)
+ {
+ fprintf (stderr,"No input file specified!\n");
+ fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
+ status = argc;
+ }
+ }
+
+ pdata->options.type = wmf_gd_image;
+
+ return (status);
+}
+
+int wmf2gd_file(PlotData* pdata, unsigned char **buf, int *w, int *h)
+{
+ int status = 0;
+
+ pdata->options.file = stdout;
+
+ status = wmf2gd_draw(pdata, buf, w, h);
+
+ if(pdata->options.file != stdout)
+ fclose(pdata->options.file);
+
+ return status;
+}
+
+int call(int argc, char **argv, unsigned char **buf, int *w, int *h)
+{
+ int status = 0;
+
+ PlotData PData;
+
+ wmf2gd_init(&PData, argc, argv);
+
+ status = wmf2gd_args(&PData);
+
+ if(status)
+ return status;
+
+ status = wmf2gd_file(&PData, buf, w, h);
+
+ return status;
+}
+
+int explicit_wmf_error (wmf_error_t err)
+{
+ int status = 0;
+
+ switch (err)
+ {
+ case wmf_E_None:
+ status = 0;
+ break;
+
+ case wmf_E_InsMem:
+ case wmf_E_BadFile:
+ case wmf_E_BadFormat:
+ case wmf_E_EOF:
+ case wmf_E_DeviceError:
+ case wmf_E_Glitch:
+ case wmf_E_Assert:
+ status = 1;
+ break;
+
+ default:
+ status = 1;
+ }
+
+ return status;
+}
diff --git a/kernel/kls_xbm/Makefile.am b/kernel/kls_xbm/Makefile.am
new file mode 100644
index 0000000..07bd070
--- /dev/null
+++ b/kernel/kls_xbm/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_xbm.la
+
+libkls_xbm_la_SOURCES = fmt_codec_xbm.cpp fmt_codec_xbm_defs.h
+
+libkls_xbm_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_xbm_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_xbm/fmt_codec_xbm.cpp b/kernel/kls_xbm/fmt_codec_xbm.cpp
new file mode 100644
index 0000000..71409ae
--- /dev/null
+++ b/kernel/kls_xbm/fmt_codec_xbm.cpp
@@ -0,0 +1,219 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_xbm_defs.h"
+#include "fmt_codec_xbm.h"
+
+#include "../xpm/codec_xbm.xpm"
+
+/*
+ *
+ * XBM is a native file format of the X Window System and is used for
+ * storing cursor and icon bitmaps that are used in the X GUI.
+ * XBMfiles are quite different in that they are actually C language source
+ * files that are created to be read by a C compiler rather than a
+ * graphical display program.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.7.0";
+ o->name = "X BitMap";
+ o->filter = "*.xbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xbm";
+ o->pixmap = codec_xbm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = fopen(file.c_str(), "rb");
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ long _tmp;
+ s8 str[256], *ptr;
+
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ if(!skip_comments(fptr))
+ return SQE_R_BADFILE;
+
+ if(!sq_fgets(str, sizeof(str)-1, fptr))
+ return SQE_R_BADFILE;
+
+ if(strncmp(str, "#define ", 8) != 0)
+ return SQE_R_BADFILE;
+
+ if((ptr = strstr(str, "_width ")) == NULL)
+ return SQE_R_BADFILE;
+
+ image.w = (long)atoi(ptr+6);
+
+ if(!sq_fgets(str, sizeof(str)-1, fptr))
+ return SQE_R_BADFILE;
+
+ if(strncmp(str, "#define ", 8) != 0)
+ return SQE_R_BADFILE;
+
+ if((ptr = strstr(str, "_height ")) == NULL)
+ return SQE_R_BADFILE;
+
+ image.h = (long)atoi(ptr+7);
+
+ while(sq_fgets(str, sizeof(str)-1, fptr))
+ {
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if(strncmp(str, "#define ", 8) != 0)
+ break;
+ }
+
+ if(str[0] == '\n') if(!sq_fgets(str, sizeof(str)-1, fptr)) return SQE_R_BADFILE;
+
+ if(strstr(str, "_bits[") == NULL || (ptr = strrchr(str, '{')) == NULL)
+ return SQE_R_BADFILE;
+
+ if((strstr(str, "unsigned") && (strstr(str, "char"))) || strstr(str, "char"))
+ version = 11;
+ else if(strstr(str, "short"))
+ version = 10;
+ else
+ return SQE_R_NOTSUPPORTED;
+
+ _tmp = lscan = image.w;
+
+ image.bpp = 1;
+
+ lscan /= 8;
+ lscan = lscan + ((_tmp%8)?1:0);
+
+ memset(pal, 255, sizeof(RGB));
+ memset(pal+1, 0, sizeof(RGB));
+
+ image.compression = "-";
+ image.colorspace = fmt_utils::colorSpaceByBpp(1);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ s8 index, c;
+ s32 counter = 0, remain = (im->w <= 8) ? im->w : (im->w % 8), j;
+ u32 bt;
+
+ for(j = 0;j < lscan;j++)
+ {
+ fscanf(fptr, "%x%c", &bt, &c);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ // @todo make faster
+ if(j==lscan-1 && (remain-0)<=0 && remain)break; index = (bt & 1); memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-1)<=0 && remain)break; index = (bt & 2) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-2)<=0 && remain)break; index = (bt & 4) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-3)<=0 && remain)break; index = (bt & 8) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-4)<=0 && remain)break; index = (bt & 16) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-5)<=0 && remain)break; index = (bt & 32) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-6)<=0 && remain)break; index = (bt & 64) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ if(j==lscan-1 && (remain-7)<=0 && remain)break; index = (bt & 128) ? 1 : 0; memcpy(scan+counter, pal+(s32)index, 3); counter++;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+/* skip a single line C-like comment */
+bool skip_comments(FILE *fp)
+{
+ s8 str[513];
+ s32 pos;
+
+ do
+ {
+ pos = ftell(fp);
+ if(!sq_fgets(str, 512, fp)) return false;
+
+ if(!strstr(str, "/*"))
+ break;
+ }while(true);
+
+ fsetpos(fp, (fpos_t*)&pos);
+
+ return true;
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_xbm/fmt_codec_xbm_defs.h b/kernel/kls_xbm/fmt_codec_xbm_defs.h
new file mode 100644
index 0000000..6204269
--- /dev/null
+++ b/kernel/kls_xbm/fmt_codec_xbm_defs.h
@@ -0,0 +1,48 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_xbm
+#define KSQUIRREL_READ_IMAGE_xbm
+
+struct XBM_HEADER
+{
+ u8 ID[3];
+
+}PACKED;
+
+bool skip_comments(FILE *);
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = fgets(s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+#endif
diff --git a/kernel/kls_xcf/Makefile.am b/kernel/kls_xcf/Makefile.am
new file mode 100644
index 0000000..6b9a50d
--- /dev/null
+++ b/kernel/kls_xcf/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = xcf2pnm
+
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_xcf.la
+
+libkls_xcf_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_xcf_la_LDFLAGS = ${SQ_RELEASE}
+libkls_xcf_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DXCF_UI=\"${pkgdatadir}/libkls_xcf.so.ui\" -DCODEC_XCF -DCODEC_ANOTHER -DKLXCF2PNM=\"${bindir}/ksquirrel-libs-xcf2pnm\"
+
+EXTRA_DIST = libkls_xcf.so.ui
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 libkls_xcf.so.ui $(DESTDIR)$(pkgdatadir)/libkls_xcf.so.ui
diff --git a/kernel/kls_xcf/fmt_codec_pnm.cpp b/kernel/kls_xcf/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_xcf/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_xcf/fmt_codec_pnm_defs.h b/kernel/kls_xcf/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_xcf/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_xcf/libkls_xcf.so.ui b/kernel/kls_xcf/libkls_xcf.so.ui
new file mode 100644
index 0000000..e0f9073
--- /dev/null
+++ b/kernel/kls_xcf/libkls_xcf.so.ui
@@ -0,0 +1,78 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Form1</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>351</width>
+ <height>59</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line5</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>autocrop</cstring>
+ </property>
+ <property name="text">
+ <string>Autocrop to visible layer boundaries</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>background</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Background color for transparent images:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<tabstops>
+ <tabstop>background</tabstop>
+ <tabstop>autocrop</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kernel/kls_xcf/xcf2pnm/Makefile.am b/kernel/kls_xcf/xcf2pnm/Makefile.am
new file mode 100644
index 0000000..c81ca26
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/Makefile.am
@@ -0,0 +1,5 @@
+bin_PROGRAMS = ksquirrel-libs-xcf2pnm
+
+ksquirrel_libs_xcf2pnm_SOURCES = enums.c flatspec.c flatten.c io-unix.c pixels.c scaletab.c table.c utils.c xcf2pnm.c xcf-general.c
+
+EXTRA_DIST = xcf2pnm.oi \ No newline at end of file
diff --git a/kernel/kls_xcf/xcf2pnm/enums.c b/kernel/kls_xcf/xcf2pnm/enums.c
new file mode 100644
index 0000000..88f68e7
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/enums.c
@@ -0,0 +1,116 @@
+/* Autogenerated from enums.h */
+#include "enums.h"
+#define N_
+#include <stdio.h>
+const char*
+showGimpLayerModeEffects(GimpLayerModeEffects x)
+{
+ static char buf[35];
+ switch(x) {
+ case GIMP_NORMAL_MODE: return N_("Normal");
+ case GIMP_DISSOLVE_MODE: return N_("Dissolve");
+ case GIMP_BEHIND_MODE: return N_("Behind");
+ case GIMP_MULTIPLY_MODE: return N_("Multiply");
+ case GIMP_SCREEN_MODE: return N_("Screen");
+ case GIMP_OVERLAY_MODE: return N_("Overlay");
+ case GIMP_DIFFERENCE_MODE: return N_("Difference");
+ case GIMP_ADDITION_MODE: return N_("Addition");
+ case GIMP_SUBTRACT_MODE: return N_("Subtract");
+ case GIMP_DARKEN_ONLY_MODE: return N_("DarkenOnly");
+ case GIMP_LIGHTEN_ONLY_MODE: return N_("LightenOnly");
+ case GIMP_HUE_MODE: return N_("Hue");
+ case GIMP_SATURATION_MODE: return N_("Saturation");
+ case GIMP_COLOR_MODE: return N_("Color");
+ case GIMP_VALUE_MODE: return N_("Value");
+ case GIMP_DIVIDE_MODE: return N_("Divide");
+ case GIMP_DODGE_MODE: return N_("Dodge");
+ case GIMP_BURN_MODE: return N_("Burn");
+ case GIMP_HARDLIGHT_MODE: return N_("Hardlight");
+ case GIMP_SOFTLIGHT_MODE: return N_("Softlight");
+ case GIMP_GRAIN_EXTRACT_MODE: return N_("GrainExtract");
+ case GIMP_GRAIN_MERGE_MODE: return N_("GrainMerge");
+ case GIMP_COLOR_ERASE_MODE: return N_("ColorErase");
+ case GIMP_ERASE_MODE: return N_("Erase");
+ case GIMP_REPLACE_MODE: return N_("Replace");
+ case GIMP_ANTI_ERASE_MODE: return N_("AntiErase");
+ case GIMP_NORMAL_NOPARTIAL_MODE: return N_("NormalNopartial");
+ default: sprintf(buf,"(GimpLayerModeEffects:%d)",(int)x);
+ return buf;
+ }
+}
+const char*
+showGimpImageBaseType(GimpImageBaseType x)
+{
+ static char buf[32];
+ switch(x) {
+ case GIMP_RGB: return N_("RGB color");
+ case GIMP_GRAY: return N_("Grayscale");
+ case GIMP_INDEXED: return N_("Indexed color");
+ default: sprintf(buf,"(GimpImageBaseType:%d)",(int)x);
+ return buf;
+ }
+}
+const char*
+showGimpImageType(GimpImageType x)
+{
+ static char buf[28];
+ switch(x) {
+ case GIMP_RGB_IMAGE: return N_("RGB");
+ case GIMP_RGBA_IMAGE: return N_("RGB-alpha");
+ case GIMP_GRAY_IMAGE: return N_("Grayscale");
+ case GIMP_GRAYA_IMAGE: return N_("Grayscale-alpha");
+ case GIMP_INDEXED_IMAGE: return N_("Indexed");
+ case GIMP_INDEXEDA_IMAGE: return N_("Indexed-alpha");
+ default: sprintf(buf,"(GimpImageType:%d)",(int)x);
+ return buf;
+ }
+}
+const char*
+showPropType(PropType x)
+{
+ static char buf[23];
+ switch(x) {
+ case PROP_END: return ("End");
+ case PROP_COLORMAP: return ("Colormap");
+ case PROP_ACTIVE_LAYER: return ("ActiveLayer");
+ case PROP_ACTIVE_CHANNEL: return ("ActiveChannel");
+ case PROP_SELECTION: return ("Selection");
+ case PROP_FLOATING_SELECTION: return ("FloatingSelection");
+ case PROP_OPACITY: return ("Opacity");
+ case PROP_MODE: return ("Mode");
+ case PROP_VISIBLE: return ("Visible");
+ case PROP_LINKED: return ("Linked");
+ case PROP_PRESERVE_TRANSPARENCY: return ("PreserveTransparency");
+ case PROP_APPLY_MASK: return ("ApplyMask");
+ case PROP_EDIT_MASK: return ("EditMask");
+ case PROP_SHOW_MASK: return ("ShowMask");
+ case PROP_SHOW_MASKED: return ("ShowMasked");
+ case PROP_OFFSETS: return ("Offsets");
+ case PROP_COLOR: return ("Color");
+ case PROP_COMPRESSION: return ("Compression");
+ case PROP_GUIDES: return ("Guides");
+ case PROP_RESOLUTION: return ("Resolution");
+ case PROP_TATTOO: return ("Tattoo");
+ case PROP_PARASITES: return ("Parasites");
+ case PROP_UNIT: return ("Unit");
+ case PROP_PATHS: return ("Paths");
+ case PROP_USER_UNIT: return ("UserUnit");
+ case PROP_VECTORS: return ("Vectors");
+ case PROP_TEXT_LAYER_FLAGS: return ("TextLayerFlags");
+ default: sprintf(buf,"(PropType:%d)",(int)x);
+ return buf;
+ }
+}
+const char*
+showXcfCompressionType(XcfCompressionType x)
+{
+ static char buf[33];
+ switch(x) {
+ case COMPRESS_NONE: return N_("None");
+ case COMPRESS_RLE: return N_("RLE");
+ case COMPRESS_ZLIB: return N_("Zlib");
+ case COMPRESS_FRACTAL: return N_("Fractal");
+ default: sprintf(buf,"(XcfCompressionType:%d)",(int)x);
+ return buf;
+ }
+}
diff --git a/kernel/kls_xcf/xcf2pnm/enums.h b/kernel/kls_xcf/xcf2pnm/enums.h
new file mode 100644
index 0000000..81746ef
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/enums.h
@@ -0,0 +1,98 @@
+/* Extracted from
+ * gimp/base-enums.h
+ * gimp/gimpbaseenums.h
+ * gimp/xcf-private.h
+ * by mkenumsh.pl
+ */
+typedef enum
+{
+ GIMP_NORMAL_MODE,
+ GIMP_DISSOLVE_MODE,
+ GIMP_BEHIND_MODE,
+ GIMP_MULTIPLY_MODE,
+ GIMP_SCREEN_MODE,
+ GIMP_OVERLAY_MODE,
+ GIMP_DIFFERENCE_MODE,
+ GIMP_ADDITION_MODE,
+ GIMP_SUBTRACT_MODE,
+ GIMP_DARKEN_ONLY_MODE,
+ GIMP_LIGHTEN_ONLY_MODE,
+ GIMP_HUE_MODE,
+ GIMP_SATURATION_MODE,
+ GIMP_COLOR_MODE,
+ GIMP_VALUE_MODE,
+ GIMP_DIVIDE_MODE,
+ GIMP_DODGE_MODE,
+ GIMP_BURN_MODE,
+ GIMP_HARDLIGHT_MODE,
+ GIMP_SOFTLIGHT_MODE,
+ GIMP_GRAIN_EXTRACT_MODE,
+ GIMP_GRAIN_MERGE_MODE,
+ GIMP_COLOR_ERASE_MODE,
+ GIMP_ERASE_MODE, /*< pdb-skip, skip >*/
+ GIMP_REPLACE_MODE, /*< pdb-skip, skip >*/
+ GIMP_ANTI_ERASE_MODE /*< pdb-skip, skip >*/
+ ,GIMP_NORMAL_NOPARTIAL_MODE=-1
+} GimpLayerModeEffects;
+const char *showGimpLayerModeEffects(GimpLayerModeEffects);
+#define GimpLayerModeEffects_LAST GIMP_ANTI_ERASE_MODE
+typedef enum
+{
+ GIMP_RGB, /*< desc="RGB color" >*/
+ GIMP_GRAY, /*< desc="Grayscale" >*/
+ GIMP_INDEXED /*< desc="Indexed color" >*/
+} GimpImageBaseType;
+const char *showGimpImageBaseType(GimpImageBaseType);
+#define GimpImageBaseType_LAST GIMP_INDEXED
+typedef enum
+{
+ GIMP_RGB_IMAGE, /*< desc="RGB" >*/
+ GIMP_RGBA_IMAGE, /*< desc="RGB-alpha" >*/
+ GIMP_GRAY_IMAGE, /*< desc="Grayscale" >*/
+ GIMP_GRAYA_IMAGE, /*< desc="Grayscale-alpha" >*/
+ GIMP_INDEXED_IMAGE, /*< desc="Indexed" >*/
+ GIMP_INDEXEDA_IMAGE /*< desc="Indexed-alpha" >*/
+} GimpImageType;
+const char *showGimpImageType(GimpImageType);
+#define GimpImageType_LAST GIMP_INDEXEDA_IMAGE
+typedef enum
+{
+ PROP_END = 0,
+ PROP_COLORMAP = 1,
+ PROP_ACTIVE_LAYER = 2,
+ PROP_ACTIVE_CHANNEL = 3,
+ PROP_SELECTION = 4,
+ PROP_FLOATING_SELECTION = 5,
+ PROP_OPACITY = 6,
+ PROP_MODE = 7,
+ PROP_VISIBLE = 8,
+ PROP_LINKED = 9,
+ PROP_PRESERVE_TRANSPARENCY = 10,
+ PROP_APPLY_MASK = 11,
+ PROP_EDIT_MASK = 12,
+ PROP_SHOW_MASK = 13,
+ PROP_SHOW_MASKED = 14,
+ PROP_OFFSETS = 15,
+ PROP_COLOR = 16,
+ PROP_COMPRESSION = 17,
+ PROP_GUIDES = 18,
+ PROP_RESOLUTION = 19,
+ PROP_TATTOO = 20,
+ PROP_PARASITES = 21,
+ PROP_UNIT = 22,
+ PROP_PATHS = 23,
+ PROP_USER_UNIT = 24,
+ PROP_VECTORS = 25,
+ PROP_TEXT_LAYER_FLAGS = 26
+} PropType;
+const char *showPropType(PropType);
+#define PropType_LAST PROP_TEXT_LAYER_FLAGS
+typedef enum
+{
+ COMPRESS_NONE = 0,
+ COMPRESS_RLE = 1,
+ COMPRESS_ZLIB = 2, /* unused */
+ COMPRESS_FRACTAL = 3 /* unused */
+} XcfCompressionType;
+const char *showXcfCompressionType(XcfCompressionType);
+#define XcfCompressionType_LAST COMPRESS_FRACTAL
diff --git a/kernel/kls_xcf/xcf2pnm/flatspec.c b/kernel/kls_xcf/xcf2pnm/flatspec.c
new file mode 100644
index 0000000..75827ff
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/flatspec.c
@@ -0,0 +1,370 @@
+/* Flattening selections function for xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xcftools.h"
+#include "flatten.h"
+#include <string.h>
+#include <stdlib.h>
+
+void
+init_flatspec(struct FlattenSpec *spec)
+{
+ spec->window_mode = USE_CANVAS ;
+ spec->default_pixel = PERHAPS_ALPHA_CHANNEL ;
+ spec->numLayers = 0 ;
+ spec->layers = NULL ;
+ spec->transmap_filename = NULL ;
+ spec->output_filename = "-" ;
+ spec->out_color_mode = COLOR_BY_CONTENTS ;
+ spec->partial_transparency_mode = ALLOW_PARTIAL_TRANSPARENCY ;
+ spec->process_in_memory = 0 ;
+ spec->gimpish_indexed = 1 ;
+}
+
+void
+add_layer_request(struct FlattenSpec *spec, const char *layer)
+{
+ spec->layers = realloc(spec->layers,
+ sizeof(struct xcfLayer) * (1+spec->numLayers));
+ if( spec->layers == NULL )
+ FatalUnexpected(_("Out of memory"));
+ spec->layers[spec->numLayers].name = layer ;
+ spec->layers[spec->numLayers].mode = (GimpLayerModeEffects)-1 ;
+ spec->layers[spec->numLayers].opacity = 9999 ;
+ spec->layers[spec->numLayers].hasMask = -1 ;
+ spec->numLayers++ ;
+}
+
+struct xcfLayer *
+lastlayerspec(struct FlattenSpec *spec,const char *option)
+{
+ if( spec->numLayers == 0 )
+ FatalGeneric(20,_("The %s option must follow a layer name on the "
+ "command line"),option);
+ return spec->layers + (spec->numLayers-1) ;
+}
+
+static int
+typeHasTransparency(GimpImageType type)
+{
+ switch( type ) {
+ case GIMP_RGB_IMAGE:
+ case GIMP_GRAY_IMAGE:
+ case GIMP_INDEXED_IMAGE:
+ return 0 ;
+ case GIMP_RGBA_IMAGE:
+ case GIMP_GRAYA_IMAGE:
+ case GIMP_INDEXEDA_IMAGE:
+ return 1 ;
+ }
+ return 1 ;
+}
+
+static enum out_color_mode
+color_by_layers(struct FlattenSpec *spec)
+{
+ int colormap_is_colored = 0 ;
+ enum out_color_mode grayish = COLOR_MONO ;
+ int i ;
+
+ if( spec->default_pixel == CHECKERED_BACKGROUND )
+ grayish = COLOR_GRAY ;
+ else if( degrayPixel(spec->default_pixel) < 0 )
+ return COLOR_RGB ;
+ for( i=0; i<colormapLength; i++ ) {
+ if( colormap[i] == NEWALPHA(0,0) || colormap[i] == NEWALPHA(-1,0) )
+ continue ;
+ if( degrayPixel(colormap[i]) == -1 ) {
+ colormap_is_colored = 1 ;
+ break ;
+ } else {
+ grayish = COLOR_GRAY ;
+ }
+ }
+ for( i=0; i<spec->numLayers; i++ )
+ switch( spec->layers[i].type ) {
+ case GIMP_RGB_IMAGE:
+ case GIMP_RGBA_IMAGE:
+ return COLOR_RGB ;
+ case GIMP_GRAY_IMAGE:
+ case GIMP_GRAYA_IMAGE:
+ grayish = COLOR_GRAY ;
+ break ;
+ case GIMP_INDEXED_IMAGE:
+ case GIMP_INDEXEDA_IMAGE:
+ if( colormap_is_colored ) return COLOR_RGB ;
+ break ;
+ }
+ return grayish ;
+}
+
+void
+complete_flatspec(struct FlattenSpec *spec, guesser guess_callback)
+{
+ unsigned i ;
+ int anyPartial ;
+
+ /* Find the layers to convert.
+ */
+ if( spec->numLayers == 0 ) {
+ spec->layers = XCF.layers ;
+ spec->numLayers = XCF.numLayers ;
+ } else {
+ for( i=0; i<spec->numLayers; i++ ) {
+ GimpLayerModeEffects mode ;
+ int opacity, hasMask ;
+ unsigned j ;
+
+ for( j=0; ; j++ ) {
+ if( j == XCF.numLayers )
+ FatalGeneric(22,_("The image has no layer called '%s'"),
+ spec->layers[i].name);
+ if( strcmp(spec->layers[i].name,XCF.layers[j].name) == 0 )
+ break ;
+ }
+ mode = spec->layers[i].mode == (GimpLayerModeEffects)-1 ?
+ XCF.layers[j].mode : spec->layers[i].mode ;
+ opacity = spec->layers[i].opacity == 9999 ?
+ XCF.layers[j].opacity : spec->layers[i].opacity ;
+ hasMask = spec->layers[i].hasMask == -1 ?
+ XCF.layers[j].hasMask : spec->layers[i].hasMask ;
+ if( hasMask && !XCF.layers[j].hasMask &&
+ XCF.layers[j].mask.hierarchy == 0 )
+ FatalGeneric(22,_("Layer '%s' has no layer mask to enable"),
+ spec->layers[i].name);
+ spec->layers[i] = XCF.layers[j] ;
+ spec->layers[i].mode = mode ;
+ spec->layers[i].opacity = opacity ;
+ spec->layers[i].hasMask = hasMask ;
+ spec->layers[i].isVisible = 1 ;
+ }
+ }
+
+ /* Force the mode of the lowest visible layer to be Normal or Dissolve.
+ * That may not be logical, but the Gimp does it
+ */
+ for( i=0; i < spec->numLayers; i++ ) {
+ if( spec->layers[i].isVisible ) {
+ if( spec->layers[i].mode != GIMP_DISSOLVE_MODE )
+ spec->layers[i].mode = GIMP_NORMAL_MODE ;
+ break ;
+ }
+ }
+
+ /* Mimic the Gimp's behavior on indexed layers */
+ if( XCF.type == GIMP_INDEXED && spec->gimpish_indexed ) {
+ for( i=0; i<spec->numLayers; i++ )
+ if( spec->layers[i].mode != GIMP_DISSOLVE_MODE )
+ spec->layers[i].mode = GIMP_NORMAL_NOPARTIAL_MODE ;
+ } else
+ spec->gimpish_indexed = 0 ;
+
+ /* compute dimensions of the window */
+ if( spec->window_mode == AUTOCROP ) {
+ int first = 1 ;
+ for( i=0; i<spec->numLayers; i++ )
+ if( spec->layers[i].isVisible ) {
+ computeDimensions(&spec->layers[i].dim) ;
+ if( first ) {
+ spec->dim = spec->layers[i].dim ;
+ first = 0 ;
+ } else {
+ if( spec->dim.c.l < spec->layers[i].dim.c.l )
+ spec->dim.c.l = spec->layers[i].dim.c.l ;
+ if( spec->dim.c.r > spec->layers[i].dim.c.r )
+ spec->dim.c.r = spec->layers[i].dim.c.r ;
+ if( spec->dim.c.t < spec->layers[i].dim.c.t )
+ spec->dim.c.t = spec->layers[i].dim.c.t ;
+ if( spec->dim.c.b > spec->layers[i].dim.c.b )
+ spec->dim.c.b = spec->layers[i].dim.c.b ;
+ }
+ }
+ if( first ) {
+ spec->window_mode = USE_CANVAS ;
+ } else {
+ spec->dim.width = spec->dim.c.r - spec->dim.c.l ;
+ spec->dim.height = spec->dim.c.b - spec->dim.c.t ;
+ }
+ }
+ if( spec->window_mode != AUTOCROP ) {
+ if( (spec->window_mode & MANUAL_OFFSET) == 0 )
+ spec->dim.c.t = spec->dim.c.l = 0 ;
+ if( (spec->window_mode & MANUAL_CROP) == 0 ) {
+ spec->dim.height = XCF.height ;
+ spec->dim.width = XCF.width ;
+ }
+ }
+ computeDimensions(&spec->dim);
+
+ /* Turn off layers that we don't hit at all */
+ for( i=0; i<spec->numLayers; i++ )
+ if( spec->layers[i].isVisible &&
+ disjointRects(spec->dim.c,spec->layers[i].dim.c) )
+ spec->layers[i].isVisible = 0 ;
+
+ /* See if there is a completely covering layer somewhere in the stack */
+ /* Also check if partial transparency is possible */
+ anyPartial = 0 ;
+ for( i=spec->numLayers; i-- ; ) {
+ if( !spec->layers[i].isVisible )
+ continue ;
+ if( typeHasTransparency(spec->layers[i].type) ) {
+ if( spec->layers[i].mode == GIMP_NORMAL_MODE )
+ anyPartial = 1;
+ } else if( isSubrect(spec->dim.c,spec->layers[i].dim.c) &&
+ (spec->layers[i].mode == GIMP_NORMAL_MODE ||
+ spec->layers[i].mode == GIMP_NORMAL_NOPARTIAL_MODE ||
+ spec->layers[i].mode == GIMP_DISSOLVE_MODE) ) {
+ /* This layer fills out the entire image.
+ * Turn off anly lower layers, and note that we cannot have
+ * transparency at all.
+ */
+ while(i) spec->layers[--i].isVisible = 0 ;
+ if( spec->default_pixel != FORCE_ALPHA_CHANNEL )
+ spec->default_pixel = NEWALPHA(colormap[0],255);
+ anyPartial = 0 ;
+ break ;
+ }
+ }
+ if( spec->partial_transparency_mode == ALLOW_PARTIAL_TRANSPARENCY &&
+ (!anyPartial || ALPHA(spec->default_pixel) >= 128) )
+ spec->partial_transparency_mode = PARTIAL_TRANSPARENCY_IMPOSSIBLE ;
+
+ /* Initialize layers and print overview if we're verbose */
+ for( i=spec->numLayers; i--; )
+ if( spec->layers[i].isVisible ) {
+ initLayer(&spec->layers[i]) ;
+ if( verboseFlag ) {
+ fprintf(stderr,"%dx%d%+d%+d %s %s",
+ spec->layers[i].dim.width, spec->layers[i].dim.height,
+ spec->layers[i].dim.c.l - spec->dim.c.l,
+ spec->layers[i].dim.c.t - spec->dim.c.t,
+ _(showGimpImageType(spec->layers[i].type)),
+ _(showGimpLayerModeEffects(spec->layers[i].mode)));
+ if( spec->layers[i].opacity < 255 )
+ fprintf(stderr,"/%02d%%",spec->layers[i].opacity * 100 / 255);
+ if( XCF.layers[i].hasMask )
+ fprintf(stderr,_("/mask"));
+ fprintf(stderr," %s\n",spec->layers[i].name);
+ }
+ }
+
+ /* Resolve color mode unless we wait until we have the entire image */
+ if( spec->out_color_mode == COLOR_BY_CONTENTS &&
+ !spec->process_in_memory ) {
+ if( guess_callback )
+ spec->out_color_mode = guess_callback(spec,NULL);
+ if( spec->out_color_mode == COLOR_BY_CONTENTS )
+ spec->out_color_mode = color_by_layers(spec) ;
+ }
+}
+
+void
+analyse_colormode(struct FlattenSpec *spec,rgba **allPixels,
+ guesser guess_callback)
+{
+ unsigned x,y ;
+ int status ;
+ /* 8 - looking for any transparency
+ * 4 - looking for partially transparent pixels
+ * 2 - looking for pixels other than black and white
+ * 1 - looking for colored pixels
+ */
+ int known_absent = 0 ;
+ int assume_present = 0 ;
+
+ if( spec->out_color_mode == COLOR_BY_CONTENTS && guess_callback )
+ spec->out_color_mode = guess_callback(spec,allPixels) ;
+
+ if( spec->out_color_mode == COLOR_RGB ) assume_present |= 3 ;
+ if( spec->out_color_mode == COLOR_INDEXED ) assume_present |= 3 ;
+ if( spec->out_color_mode == COLOR_GRAY ) assume_present |= 2 ;
+ switch( color_by_layers(spec) ) {
+ case COLOR_GRAY: known_absent |= 1 ; break ;
+ case COLOR_MONO: known_absent |= 3 ; break ;
+ default: break ;
+ }
+ if( spec->partial_transparency_mode == DISSOLVE_PARTIAL_TRANSPARENCY ||
+ spec->partial_transparency_mode == PARTIAL_TRANSPARENCY_IMPOSSIBLE )
+ known_absent |= 4 ;
+ if( ALPHA(spec->default_pixel) >= 128 ) known_absent |= 12 ;
+ else if( spec->default_pixel == FORCE_ALPHA_CHANNEL ) assume_present |= 8 ;
+
+ status = 15 - (known_absent | assume_present) ;
+
+ for( y=0; status && y<spec->dim.height; y++ ) {
+ rgba *row = allPixels[y] ;
+ if( (status & 3) != 0 ) {
+ /* We're still interested in color */
+ for( x=0; status && x<spec->dim.width; x++ ) {
+ if( NULLALPHA(row[x]) )
+ status &= ~8 ;
+ else {
+ rgba full = row[x] | (255 << ALPHA_SHIFT) ;
+ if( !FULLALPHA(row[x]) ) status &= ~12 ;
+ if( full == NEWALPHA(0,255) || full == NEWALPHA(-1,255) )
+ /* Black or white */ ;
+ else if( degrayPixel(row[x]) != -1 )
+ status &= ~2 ; /* gray */
+ else
+ status &= ~3 ; /* color */
+ }
+ }
+ } else {
+ /* Not interested in color */
+ for( x=0; status && x<spec->dim.width; x++ ) {
+ if( NULLALPHA(row[x]) )
+ status &= ~8 ;
+ else if( !FULLALPHA(row[x]) )
+ status &= ~12 ;
+ }
+ }
+ }
+
+ status |= known_absent ;
+
+ switch( spec->out_color_mode ) {
+ case COLOR_INDEXED: /* The caller takes responsibility */
+ case COLOR_RGB: /* Everything is fine. */
+ break ;
+ case COLOR_GRAY:
+ if( (status & 1) == 0 )
+ FatalGeneric(103,
+ _("Grayscale output selected, but colored pixel(s) found"));
+ break ;
+ case COLOR_MONO:
+ if( (status & 2) == 0 )
+ FatalGeneric(103,_("Monochrome output selected, but not all pixels "
+ "are black or white"));
+ break ;
+ case COLOR_BY_FILENAME: /* Should not happen ... */
+ case COLOR_BY_CONTENTS:
+ if( (status & 1) == 0 )
+ spec->out_color_mode = COLOR_RGB ;
+ else if( (status & 2) == 0 )
+ spec->out_color_mode = COLOR_GRAY ;
+ else
+ spec->out_color_mode = COLOR_MONO ;
+ break ;
+ }
+
+ if( (status & 12) == 12 ) /* No transparency found */
+ spec->default_pixel = NEWALPHA(colormap[0],255);
+ else if( (status & 12) == 4 )
+ spec->partial_transparency_mode = PARTIAL_TRANSPARENCY_IMPOSSIBLE ;
+}
diff --git a/kernel/kls_xcf/xcf2pnm/flatten.c b/kernel/kls_xcf/xcf2pnm/flatten.c
new file mode 100644
index 0000000..c564ddd
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/flatten.c
@@ -0,0 +1,689 @@
+/* Flattning functions for xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xcftools.h"
+#include "flatten.h"
+#include "pixels.h"
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+static rgba __ATTRIBUTE__((noinline,const))
+composite_one(rgba bot,rgba top)
+{
+ unsigned tfrac, alpha ;
+
+ tfrac = ALPHA(top) ;
+ alpha = 255 ;
+ if( !FULLALPHA(bot) ) {
+ alpha = 255 ^ scaletable[255-ALPHA(bot)][255-ALPHA(top)] ;
+ /* This peculiar combination of ^ and - makes the GCC code
+ * generator for i386 particularly happy.
+ */
+ tfrac = (256*ALPHA(top) - 1) / alpha ;
+ /* Tfrac is the fraction of the coposited pixel's covered area
+ * that comes from the top pixel.
+ * For mathematical accuracy we ought to scale by 255 and
+ * subtract alpha/2, but this is faster, and never misses the
+ * true value by more than one 1/255. This effect is completely
+ * overshadowed by the linear interpolation in the first place.
+ * (I.e. gamma is ignored when combining intensities).
+ * [In any case, complete fairness is not possible: if the
+ * bottom pixel had alpha=170 and the top has alpha=102,
+ * each should contribute equally to the color of the
+ * resulting alpha=204 pixel, which is not possible in general]
+ * Subtracting one helps the topfrac never be 256, which would
+ * be bad.
+ * On the other hand it means that we would get tfrac=-1 if the
+ * top pixel is completely transparent, and we get a division
+ * by zero if _both_ pixels are fully transparent. These cases
+ * must be handled by all callers.
+ * More snooping in the Gimp sources reveal that it uses
+ * floating-point for its equivalent of tfrac when the
+ * bottom layer has an alpha channel. (alphify() macro
+ * in paint-funcs.c). What gives?
+ */
+ }
+ return (alpha << ALPHA_SHIFT)
+ + ((uint32_t)scaletable[ tfrac ][255&(top>>RED_SHIFT )] << RED_SHIFT )
+ + ((uint32_t)scaletable[ tfrac ][255&(top>>GREEN_SHIFT)] << GREEN_SHIFT )
+ + ((uint32_t)scaletable[ tfrac ][255&(top>>BLUE_SHIFT )] << BLUE_SHIFT )
+ + ((uint32_t)scaletable[255^tfrac][255&(bot>>RED_SHIFT )] << RED_SHIFT )
+ + ((uint32_t)scaletable[255^tfrac][255&(bot>>GREEN_SHIFT)] << GREEN_SHIFT )
+ + ((uint32_t)scaletable[255^tfrac][255&(bot>>BLUE_SHIFT )] << BLUE_SHIFT )
+ ;
+}
+
+/* merge_normal() takes ownership of bot.
+ * merge_normal() will share ownership of top.
+ * Return: may be shared.
+ */
+static struct Tile * __ATTRIBUTE__((noinline))
+merge_normal(struct Tile *bot, struct Tile *top)
+{
+ unsigned i ;
+ assertTileCompatibility(bot,top);
+
+ /* See if there is an easy winner */
+ if( (bot->summary & TILESUMMARY_ALLNULL) ||
+ (top->summary & TILESUMMARY_ALLFULL) ) {
+ freeTile(bot);
+ return top ;
+ }
+ if( top->summary & TILESUMMARY_ALLNULL ) {
+ freeTile(top);
+ return bot ;
+ }
+
+ /* Try hard to make top win */
+ for( i=0; ; i++ ) {
+ if( i == top->count ) {
+ freeTile(bot);
+ return top ;
+ }
+ if( !(NULLALPHA(bot->pixels[i]) || FULLALPHA(top->pixels[i])) )
+ break ;
+ }
+
+ INIT_SCALETABLE_IF( !(top->summary & TILESUMMARY_CRISP) );
+
+ /* Otherwise bot wins, but is forever changed ... */
+ if( (top->summary & TILESUMMARY_ALLNULL) == 0 ) {
+ unsigned i ;
+ invalidateSummary(bot,0);
+ for( i=0 ; i < top->count ; i++ ) {
+ if( !NULLALPHA(top->pixels[i]) ) {
+ if( FULLALPHA(top->pixels[i]) || NULLALPHA(bot->pixels[i]) )
+ bot->pixels[i] = top->pixels[i] ;
+ else
+ bot->pixels[i] = composite_one(bot->pixels[i],top->pixels[i]);
+ }
+ }
+ }
+ freeTile(top);
+ return bot ;
+}
+
+#define exotic_combinator static inline unsigned __ATTRIBUTE__((const))
+
+
+
+exotic_combinator
+ucombine_ADDITION(uint8_t bot,uint8_t top)
+{
+ return bot+top > 255 ? 255 : bot+top ;
+}
+
+exotic_combinator
+ucombine_SUBTRACT(uint8_t bot,uint8_t top)
+{
+ return top>bot ? 0 : bot-top ;
+}
+
+exotic_combinator
+ucombine_LIGHTEN_ONLY(uint8_t bot,uint8_t top)
+{
+ return top > bot ? top : bot ;
+}
+
+exotic_combinator
+ucombine_DARKEN_ONLY(uint8_t bot,uint8_t top)
+{
+ return top < bot ? top : bot ;
+}
+
+exotic_combinator
+ucombine_DIFFERENCE(uint8_t bot,uint8_t top)
+{
+ return top > bot ? top-bot : bot-top ;
+}
+
+exotic_combinator
+ucombine_MULTIPLY(uint8_t bot,uint8_t top)
+{
+ return scaletable[bot][top] ;
+}
+
+exotic_combinator
+ucombine_DIVIDE(uint8_t bot,uint8_t top)
+{
+ int result = (int)bot*256 / (1+top) ;
+ return result >= 256 ? 255 : result ;
+}
+
+exotic_combinator
+ucombine_SCREEN(uint8_t bot,uint8_t top)
+{
+ /* An inverted version of "multiply" */
+ return 255 ^ scaletable[255-bot][255-top] ;
+}
+
+exotic_combinator
+ucombine_OVERLAY(uint8_t bot,uint8_t top)
+{
+ return scaletable[bot][bot] +
+ 2*scaletable[top][scaletable[bot][255-bot]] ;
+ /* This strange formula is equivalent to
+ * (1-top)*(bot^2) + top*(1-(1-top)^2)
+ * that is, the top value is used to interpolate between
+ * the self-multiply and the self-screen of the bottom.
+ */
+ /* Note: This is exactly what the "Soft light" effect also
+ * does, though with different code in the Gimp.
+ */
+}
+
+exotic_combinator
+ucombine_DODGE(uint8_t bot,uint8_t top)
+{
+ return ucombine_DIVIDE(bot,255-top);
+}
+
+exotic_combinator
+ucombine_BURN(uint8_t bot,uint8_t top)
+{
+ return 255 - ucombine_DIVIDE(255-bot,top);
+}
+
+exotic_combinator
+ucombine_HARDLIGHT(uint8_t bot,uint8_t top)
+{
+ if( top >= 128 )
+ return 255 ^ scaletable[255-bot][2*(255-top)] ;
+ else
+ return scaletable[bot][2*top];
+ /* The code that implements "hardlight" in Gimp 2.2.10 has some
+ * rounding errors, but this is undoubtedly what is meant.
+ */
+}
+
+exotic_combinator
+ucombine_GRAIN_EXTRACT(uint8_t bot,uint8_t top)
+{
+ int temp = (int)bot - (int)top + 128 ;
+ return temp < 0 ? 0 : temp >= 256 ? 255 : temp ;
+}
+
+exotic_combinator
+ucombine_GRAIN_MERGE(uint8_t bot,uint8_t top)
+{
+ int temp = (int)bot + (int)top - 128 ;
+ return temp < 0 ? 0 : temp >= 256 ? 255 : temp ;
+}
+
+struct HSV {
+ enum { HUE_RED_GREEN_BLUE,HUE_RED_BLUE_GREEN,HUE_BLUE_RED_GREEN,
+ HUE_BLUE_GREEN_RED,HUE_GREEN_BLUE_RED,HUE_GREEN_RED_BLUE } hue;
+ unsigned ch1, ch2, ch3 ;
+};
+
+static void
+RGBtoHSV(rgba rgb,struct HSV *hsv)
+{
+ unsigned RED = (uint8_t)(rgb >> RED_SHIFT);
+ unsigned GREEN = (uint8_t)(rgb >> GREEN_SHIFT);
+ unsigned BLUE = (uint8_t)(rgb >> BLUE_SHIFT) ;
+ #define HEXTANT(b,m,t) hsv->ch1 = b, hsv->ch2 = m, hsv->ch3 = t, \
+ hsv->hue = HUE_ ## b ## _ ## m ## _ ## t
+ if( GREEN <= RED )
+ if( BLUE <= RED )
+ if( GREEN <= BLUE )
+ HEXTANT(GREEN,BLUE,RED);
+ else
+ HEXTANT(BLUE,GREEN,RED);
+ else
+ HEXTANT(GREEN,RED,BLUE);
+ else if( BLUE <= RED )
+ HEXTANT(BLUE,RED,GREEN);
+ else if( BLUE <= GREEN )
+ HEXTANT(RED,BLUE,GREEN);
+ else
+ HEXTANT(RED,GREEN,BLUE);
+ #undef HEXTANT
+}
+
+/* merge_exotic() destructively updates bot.
+ * merge_exotic() reads but does not free top.
+ */
+static void __ATTRIBUTE__((noinline))
+merge_exotic(struct Tile *bot, const struct Tile *top,
+ GimpLayerModeEffects mode)
+{
+ unsigned i ;
+ assertTileCompatibility(bot,top);
+ if( (bot->summary & TILESUMMARY_ALLNULL) != 0 ) return ;
+ if( (top->summary & TILESUMMARY_ALLNULL) != 0 ) return ;
+ assert( bot->refcount == 1 );
+ /* The transparency status of bot never changes */
+
+ INIT_SCALETABLE_IF(1);
+
+ for( i=0; i < top->count ; i++ ) {
+ uint32_t RED, GREEN, BLUE ;
+ if( NULLALPHA(bot->pixels[i]) || NULLALPHA(top->pixels[i]) )
+ continue ;
+#define UNIFORM(mode) case GIMP_ ## mode ## _MODE: \
+ RED = ucombine_ ## mode (bot->pixels[i]>>RED_SHIFT , \
+ top->pixels[i]>>RED_SHIFT ); \
+ GREEN = ucombine_ ## mode (bot->pixels[i]>>GREEN_SHIFT, \
+ top->pixels[i]>>GREEN_SHIFT); \
+ BLUE = ucombine_ ## mode (bot->pixels[i]>>BLUE_SHIFT , \
+ top->pixels[i]>>BLUE_SHIFT ); \
+ break ;
+ switch( mode ) {
+ case GIMP_NORMAL_MODE:
+ case GIMP_DISSOLVE_MODE:
+ FatalUnexpected("Normal and Dissolve mode can't happen here!");
+ UNIFORM(ADDITION);
+ UNIFORM(SUBTRACT);
+ UNIFORM(LIGHTEN_ONLY);
+ UNIFORM(DARKEN_ONLY);
+ UNIFORM(DIFFERENCE);
+ UNIFORM(MULTIPLY);
+ UNIFORM(DIVIDE);
+ UNIFORM(SCREEN);
+ case GIMP_SOFTLIGHT_MODE: /* A synonym for "overlay"! */
+ UNIFORM(OVERLAY);
+ UNIFORM(DODGE);
+ UNIFORM(BURN);
+ UNIFORM(HARDLIGHT);
+ UNIFORM(GRAIN_EXTRACT);
+ UNIFORM(GRAIN_MERGE);
+ case GIMP_HUE_MODE:
+ case GIMP_SATURATION_MODE:
+ case GIMP_VALUE_MODE:
+ case GIMP_COLOR_MODE:
+ {
+ static struct HSV hsvTop, hsvBot ;
+ RGBtoHSV(top->pixels[i],&hsvTop);
+ if( mode == GIMP_HUE_MODE && hsvTop.ch1 == hsvTop.ch3 )
+ continue ;
+ RGBtoHSV(bot->pixels[i],&hsvBot);
+ if( mode == GIMP_VALUE_MODE ) {
+ if( hsvBot.ch3 ) {
+ hsvBot.ch1 = (hsvBot.ch1*hsvTop.ch3 + hsvBot.ch3/2) / hsvBot.ch3;
+ hsvBot.ch2 = (hsvBot.ch2*hsvTop.ch3 + hsvBot.ch3/2) / hsvBot.ch3;
+ hsvBot.ch3 = hsvTop.ch3 ;
+ } else {
+ hsvBot.ch1 = hsvBot.ch2 = hsvBot.ch3 = hsvTop.ch3 ;
+ }
+ } else {
+ unsigned mfNum, mfDenom ;
+ if( mode == GIMP_HUE_MODE || mode == GIMP_COLOR_MODE ) {
+ mfNum = hsvTop.ch2-hsvTop.ch1 ;
+ mfDenom = hsvTop.ch3-hsvTop.ch1 ;
+ hsvBot.hue = hsvTop.hue ;
+ } else {
+ mfNum = hsvBot.ch2-hsvBot.ch1 ;
+ mfDenom = hsvBot.ch3-hsvBot.ch1 ;
+ }
+ if( mode == GIMP_SATURATION_MODE ) {
+ if( hsvTop.ch3 == 0 )
+ hsvBot.ch1 = hsvBot.ch3 ; /* Black has no saturation */
+ else
+ hsvBot.ch1 = (hsvTop.ch1*hsvBot.ch3 + hsvTop.ch3/2) / hsvTop.ch3;
+ } else if( mode == GIMP_COLOR_MODE ) {
+ /* GIMP_COLOR_MODE works in HSL space instead of HSV. We must
+ * transfer H and S, keeping the L = ch1+ch3 of the bottom pixel,
+ * but the S we transfer works differently from the S in HSV.
+ */
+ unsigned L = hsvTop.ch1 + hsvTop.ch3 ;
+ unsigned sNum = hsvTop.ch3 - hsvTop.ch1 ;
+ unsigned sDenom = L < 256 ? L : 510-L ;
+ if( sDenom == 0 ) sDenom = 1 ; /* sNum will be 0 */
+ L = hsvBot.ch1 + hsvBot.ch3 ;
+ if( L < 256 ) {
+ /* Ideally we want to compute L/2 * (1-sNum/sDenom)
+ * But shuffle this a bit so we can use integer arithmetic.
+ * The "-1" in the rounding prevents us from ending up with
+ * ch1 > ch3.
+ */
+ hsvBot.ch1 = (L*(sDenom-sNum)+sDenom-1)/(2*sDenom);
+ hsvBot.ch3 = L - hsvBot.ch1 ;
+ } else {
+ /* Here our goal is 255 - (510-L)/2 * (1-sNum/sDenom) */
+ hsvBot.ch3 = 255 - ((510-L)*(sDenom-sNum)+sDenom-1)/(2*sDenom);
+ hsvBot.ch1 = L - hsvBot.ch3 ;
+ }
+ assert(hsvBot.ch3 <= 255);
+ assert(hsvBot.ch3 >= hsvBot.ch1);
+ }
+ if( mfDenom == 0 )
+ hsvBot.ch2 = hsvBot.ch1 ;
+ else
+ hsvBot.ch2 = hsvBot.ch1 +
+ (mfNum*(hsvBot.ch3-hsvBot.ch1) + mfDenom/2) / mfDenom ;
+ }
+ switch( hsvBot.hue ) {
+ #define HEXTANT(b,m,t) case HUE_ ## b ## _ ## m ## _ ## t : \
+ b = hsvBot.ch1; m = hsvBot.ch2; t = hsvBot.ch3; break;
+ HEXTANT(RED,GREEN,BLUE);
+ HEXTANT(RED,BLUE,GREEN);
+ HEXTANT(BLUE,RED,GREEN);
+ HEXTANT(BLUE,GREEN,RED);
+ HEXTANT(GREEN,BLUE,RED);
+ HEXTANT(GREEN,RED,BLUE);
+ #undef HEXTANT
+ }
+ break ;
+ }
+ default:
+ FatalUnsupportedXCF(_("'%s' layer mode"),
+ _(showGimpLayerModeEffects(mode)));
+ }
+ if( FULLALPHA(bot->pixels[i] & top->pixels[i]) )
+ bot->pixels[i] = (bot->pixels[i] & (255 << ALPHA_SHIFT)) +
+ (RED << RED_SHIFT) +
+ (GREEN << GREEN_SHIFT) +
+ (BLUE << BLUE_SHIFT) ;
+ else {
+ rgba bp = bot->pixels[i] ;
+ /* In a sane world, the alpha of the top pixel would simply be
+ * used to interpolate linearly between the bottom pixel's base
+ * color and the effect-computed color.
+ * But no! What the Gimp actually does is empirically
+ * described by the following (which borrows code from
+ * composite_one() that makes no theoretical sense here):
+ */
+ unsigned tfrac = ALPHA(top->pixels[i]) ;
+ if( !FULLALPHA(bp) ) {
+ unsigned pseudotop = (tfrac < ALPHA(bp) ? tfrac : ALPHA(bp));
+ unsigned alpha = 255 ^ scaletable[255-ALPHA(bp)][255-pseudotop] ;
+ tfrac = (256*pseudotop - 1) / alpha ;
+ }
+ bot->pixels[i] = (bp & (255 << ALPHA_SHIFT)) +
+ ((rgba)scaletable[ tfrac ][ RED ] << RED_SHIFT ) +
+ ((rgba)scaletable[ tfrac ][ GREEN ] << GREEN_SHIFT) +
+ ((rgba)scaletable[ tfrac ][ BLUE ] << BLUE_SHIFT ) +
+ ((rgba)scaletable[255^tfrac][255&(bp>>RED_SHIFT )] << RED_SHIFT ) +
+ ((rgba)scaletable[255^tfrac][255&(bp>>GREEN_SHIFT)] << GREEN_SHIFT) +
+ ((rgba)scaletable[255^tfrac][255&(bp>>BLUE_SHIFT )] << BLUE_SHIFT ) ;
+ }
+ }
+ return ;
+}
+
+static void
+dissolveTile(struct Tile *tile)
+{
+ unsigned i ;
+ summary_t summary ;
+ assert( tile->refcount == 1 );
+ if( (tile->summary & TILESUMMARY_CRISP) )
+ return ;
+ summary = TILESUMMARY_UPTODATE + TILESUMMARY_ALLNULL
+ + TILESUMMARY_ALLFULL + TILESUMMARY_CRISP ;
+ for( i = 0 ; i < tile->count ; i++ ) {
+ if( FULLALPHA(tile->pixels[i]) )
+ summary &= ~TILESUMMARY_ALLNULL ;
+ else if ( NULLALPHA(tile->pixels[i]) )
+ summary &= ~TILESUMMARY_ALLFULL ;
+ else if( ALPHA(tile->pixels[i]) > rand() % 0xFF ) {
+ tile->pixels[i] |= 255 << ALPHA_SHIFT ;
+ summary &= ~TILESUMMARY_ALLNULL ;
+ } else {
+ tile->pixels[i] = 0 ;
+ summary &= ~TILESUMMARY_ALLFULL ;
+ }
+ }
+ tile->summary = summary ;
+}
+
+static void
+roundAlpha(struct Tile *tile)
+{
+ unsigned i ;
+ summary_t summary ;
+ assert( tile->refcount == 1 );
+ if( (tile->summary & TILESUMMARY_CRISP) )
+ return ;
+ summary = TILESUMMARY_UPTODATE + TILESUMMARY_ALLNULL
+ + TILESUMMARY_ALLFULL + TILESUMMARY_CRISP ;
+ for( i = 0 ; i < tile->count ; i++ ) {
+ if( ALPHA(tile->pixels[i]) >= 128 ) {
+ tile->pixels[i] |= 255 << ALPHA_SHIFT ;
+ summary &= ~TILESUMMARY_ALLNULL ;
+ } else {
+ tile->pixels[i] = 0 ;
+ summary &= ~TILESUMMARY_ALLFULL ;
+ }
+ }
+ tile->summary = summary ;
+}
+
+/* flattenTopdown() shares ownership of top.
+ * The return value may be a shared tile.
+ */
+static struct Tile *
+flattenTopdown(struct FlattenSpec *spec, struct Tile *top,
+ unsigned nlayers, const struct rect *where)
+{
+ struct Tile *tile;
+
+ while( nlayers-- ) {
+ if( tileSummary(top) & TILESUMMARY_ALLFULL )
+ return top ;
+ if( !spec->layers[nlayers].isVisible )
+ continue ;
+
+ tile = getLayerTile(&spec->layers[nlayers],where);
+
+ if( tile->summary & TILESUMMARY_ALLNULL )
+ continue ; /* Simulate a tail call */
+
+ switch( spec->layers[nlayers].mode ) {
+ case GIMP_NORMAL_NOPARTIAL_MODE:
+ roundAlpha(tile) ;
+ /* fall through */
+ if(0) {
+ case GIMP_DISSOLVE_MODE:
+ dissolveTile(tile);
+ /* fall through */
+ }
+ case GIMP_NORMAL_MODE:
+ top = merge_normal(tile,top);
+ break ;
+ default:
+ {
+ struct Tile *below, *above ;
+ unsigned i ;
+ if( !(top->summary & TILESUMMARY_ALLNULL) ) {
+ rgba tile_or = 0 ;
+ invalidateSummary(tile,0);
+ for( i=0; i<top->count; i++ )
+ if( FULLALPHA(top->pixels[i]) )
+ tile->pixels[i] = 0 ;
+ else
+ tile_or |= tile->pixels[i] ;
+ /* If the tile only has pixels that will be covered by 'top' anyway,
+ * forget it anyway.
+ */
+ if( ALPHA(tile_or) == 0 ) {
+ freeTile(tile);
+ break ; /* from the switch, which will continue the while */
+ }
+ }
+ /* Create a dummy top for the layers below this */
+ if( top->summary & TILESUMMARY_CRISP ) {
+ above = forkTile(top);
+ } else {
+ summary_t summary = TILESUMMARY_ALLNULL ;
+ above = newTile(*where);
+ for( i=0; i<top->count; i++ )
+ if( FULLALPHA(top->pixels[i]) ) {
+ above->pixels[i] = -1 ;
+ summary = 0 ;
+ } else
+ above->pixels[i] = 0 ;
+ above->summary = TILESUMMARY_UPTODATE + TILESUMMARY_CRISP + summary;
+ }
+ below = flattenTopdown(spec, above, nlayers, where);
+ if( below->refcount > 1 ) {
+ assert( below == top );
+ /* This can only happen if 'below' is a copy of 'top'
+ * THROUGH 'above', which in turn means that none of all
+ * this is visible after all. So just free it and return 'top'.
+ */
+ freeTile(below);
+ return top ;
+ }
+ merge_exotic(below,tile,spec->layers[nlayers].mode);
+ freeTile(tile);
+ top = merge_normal(below,top);
+ return top ;
+ }
+ }
+ }
+ return top ;
+}
+
+static void
+addBackground(struct FlattenSpec *spec, struct Tile *tile, unsigned ncols)
+{
+ unsigned i ;
+
+ if( tileSummary(tile) & TILESUMMARY_ALLFULL )
+ return ;
+
+ switch( spec->partial_transparency_mode ) {
+ case FORBID_PARTIAL_TRANSPARENCY:
+ if( !(tileSummary(tile) & TILESUMMARY_CRISP) )
+ FatalGeneric(102,_("Flattened image has partially transparent pixels"));
+ break ;
+ case DISSOLVE_PARTIAL_TRANSPARENCY:
+ dissolveTile(tile);
+ break ;
+ case ALLOW_PARTIAL_TRANSPARENCY:
+ case PARTIAL_TRANSPARENCY_IMPOSSIBLE:
+ break ;
+ }
+
+ if( spec->default_pixel == CHECKERED_BACKGROUND ) {
+ INIT_SCALETABLE_IF( !(tile->summary & TILESUMMARY_CRISP ) );
+ for( i=0; i<tile->count; i++ )
+ if( !FULLALPHA(tile->pixels[i]) ) {
+ rgba fillwith = ((i/ncols)^(i%ncols))&8 ? 0x66 : 0x99 ;
+ fillwith = graytable[fillwith] + (255 << ALPHA_SHIFT) ;
+ if( NULLALPHA(tile->pixels[i]) )
+ tile->pixels[i] = fillwith ;
+ else
+ tile->pixels[i] = composite_one(fillwith,tile->pixels[i]);
+ }
+ tile->summary = TILESUMMARY_UPTODATE +
+ TILESUMMARY_ALLFULL + TILESUMMARY_CRISP ;
+ return ;
+ }
+ if( !FULLALPHA(spec->default_pixel) ) return ;
+ if( tileSummary(tile) & TILESUMMARY_ALLNULL ) {
+ fillTile(tile,spec->default_pixel);
+ } else {
+ INIT_SCALETABLE_IF( !(tile->summary & TILESUMMARY_CRISP) );
+ for( i=0; i<tile->count; i++ )
+ if( NULLALPHA(tile->pixels[i]) )
+ tile->pixels[i] = spec->default_pixel ;
+ else if( FULLALPHA(tile->pixels[i]) )
+ ;
+ else
+ tile->pixels[i] = composite_one(spec->default_pixel,tile->pixels[i]);
+
+ tile->summary = TILESUMMARY_UPTODATE +
+ TILESUMMARY_ALLFULL + TILESUMMARY_CRISP ;
+ }
+}
+
+void
+flattenIncrementally(struct FlattenSpec *spec,lineCallback callback)
+{
+ rgba *rows[TILE_HEIGHT] ;
+ unsigned i, y, nrows, ncols ;
+ struct rect where ;
+ struct Tile *tile ;
+ static struct Tile toptile ;
+
+ toptile.count = TILE_HEIGHT * TILE_WIDTH ;
+ fillTile(&toptile,0);
+
+ for( where.t = spec->dim.c.t; where.t < spec->dim.c.b; where.t=where.b ) {
+ where.b = (where.t+TILE_HEIGHT) - where.t % TILE_HEIGHT ;
+ if( where.b > spec->dim.c.b ) where.b = spec->dim.c.b ;
+ nrows = where.b - where.t ;
+ for( y = 0; y < nrows ; y++ )
+ rows[y] = xcfmalloc(4*(spec->dim.c.r-spec->dim.c.l));
+
+ for( where.l = spec->dim.c.l; where.l < spec->dim.c.r; where.l=where.r ) {
+ where.r = (where.l+TILE_WIDTH) - where.l % TILE_WIDTH ;
+ if( where.r > spec->dim.c.r ) where.r = spec->dim.c.r ;
+ ncols = where.r - where.l ;
+
+ toptile.count = ncols * nrows ;
+ toptile.refcount = 2 ; /* For bug checking */
+ assert( toptile.summary == TILESUMMARY_UPTODATE +
+ TILESUMMARY_ALLNULL + TILESUMMARY_CRISP );
+ tile = flattenTopdown(spec,&toptile,spec->numLayers,&where) ;
+ toptile.refcount-- ; /* addBackground may change destructively */
+ addBackground(spec,tile,ncols);
+
+ for( i = 0 ; i < tile->count ; i++ )
+ if( NULLALPHA(tile->pixels[i]) )
+ tile->pixels[i] = 0 ;
+ for( y = 0 ; y < nrows ; y++ )
+ memcpy(rows[y] + (where.l - spec->dim.c.l),
+ tile->pixels + y * ncols, ncols*4);
+
+ if( tile == &toptile ) {
+ fillTile(&toptile,0);
+ } else {
+ freeTile(tile);
+ }
+ }
+ for( y = 0 ; y < nrows ; y++ )
+ callback(spec->dim.width,rows[y]);
+ }
+}
+
+static rgba **collectPointer ;
+
+static void
+collector(unsigned num,rgba *row)
+{
+ *collectPointer++ = row ;
+}
+
+rgba **
+flattenAll(struct FlattenSpec *spec)
+{
+ rgba **rows = xcfmalloc(spec->dim.height * sizeof(rgba*));
+ if( verboseFlag )
+ fprintf(stderr,_("Flattening image ..."));
+ collectPointer = rows ;
+ flattenIncrementally(spec,collector);
+ if( verboseFlag )
+ fprintf(stderr,"\n");
+ return rows ;
+}
+
+void
+shipoutWithCallback(struct FlattenSpec *spec, rgba **pixels,
+ lineCallback callback)
+{
+ unsigned i ;
+ for( i = 0; i < spec->dim.height; i++ ) {
+ callback(spec->dim.width,pixels[i]);
+ }
+ xcffree(pixels);
+}
diff --git a/kernel/kls_xcf/xcf2pnm/flatten.h b/kernel/kls_xcf/xcf2pnm/flatten.h
new file mode 100644
index 0000000..c252175
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/flatten.h
@@ -0,0 +1,77 @@
+/* Flattning functions for xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FLATTEN_H
+#define FLATTEN_H
+
+#include "xcftools.h"
+#include "pixels.h"
+
+#define PERHAPS_ALPHA_CHANNEL (NEWALPHA(0,1))
+#define FORCE_ALPHA_CHANNEL (NEWALPHA(0,2))
+#define CHECKERED_BACKGROUND (NEWALPHA(0,200))
+struct FlattenSpec {
+ struct tileDimensions dim ;
+ rgba default_pixel ;
+ int numLayers ;
+ struct xcfLayer *layers ;
+
+ const char * transmap_filename ;
+ const char * output_filename ;
+ enum out_color_mode {
+ COLOR_BY_FILENAME,
+ COLOR_BY_CONTENTS,
+ COLOR_INDEXED,
+ COLOR_RGB,
+ COLOR_GRAY,
+ COLOR_MONO
+ } out_color_mode ;
+ enum { ALLOW_PARTIAL_TRANSPARENCY,
+ DISSOLVE_PARTIAL_TRANSPARENCY,
+ FORBID_PARTIAL_TRANSPARENCY,
+ PARTIAL_TRANSPARENCY_IMPOSSIBLE
+ } partial_transparency_mode ;
+ enum { USE_CANVAS = 0,
+ MANUAL_OFFSET = 1,
+ MANUAL_CROP = 2,
+ AUTOCROP = 4 } window_mode ;
+ int process_in_memory ;
+ int gimpish_indexed ;
+};
+
+/* From flatspec.c */
+
+void init_flatspec(struct FlattenSpec *);
+
+void add_layer_request(struct FlattenSpec *,const char *name);
+struct xcfLayer *lastlayerspec(struct FlattenSpec *,const char *option);
+
+typedef enum out_color_mode (*guesser) (struct FlattenSpec *,rgba **);
+
+/* Call this after processing options, and after opening the XCF file */
+void complete_flatspec(struct FlattenSpec *,guesser);
+void analyse_colormode(struct FlattenSpec *,rgba **allPixels,guesser);
+
+/* From flatten.c */
+
+typedef void (*lineCallback)(unsigned num,rgba *pixels);
+void flattenIncrementally(struct FlattenSpec *,lineCallback);
+rgba **flattenAll(struct FlattenSpec*);
+void shipoutWithCallback(struct FlattenSpec *,rgba **pixels,lineCallback);
+
+#endif /* FLATTEN_H */
diff --git a/kernel/kls_xcf/xcf2pnm/io-unix.c b/kernel/kls_xcf/xcf2pnm/io-unix.c
new file mode 100644
index 0000000..38dc4e4
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/io-unix.c
@@ -0,0 +1,176 @@
+/* OS-specific IO functions for xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xcftools.h"
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+static FILE *xcfstream = 0 ;
+
+void
+free_or_close_xcf(void)
+{
+ if( xcf_file ) {
+ if( xcfstream ) {
+ munmap(xcf_file,xcf_length) ;
+ fclose(xcfstream);
+ xcf_file = 0 ;
+ xcfstream = 0 ;
+ } else {
+ free(xcf_file) ;
+ xcf_file = 0 ;
+ }
+ }
+}
+
+void
+read_or_mmap_xcf(const char *filename,const char *unzipper)
+{
+ struct stat statbuf ;
+
+ free_or_close_xcf() ;
+
+ if( strcmp(filename,"-") != 0 ) {
+ if( access(filename,R_OK) != 0 )
+ FatalGeneric(21,"!%s",filename);
+ }
+
+ if( !unzipper ) {
+ const char *pc ;
+ pc = filename + strlen(filename) ;
+ if( pc-filename > 2 && strcmp(pc-2,"gz") == 0 )
+ unzipper = "zcat" ;
+ else if ( pc-filename > 3 && strcmp(pc-3,"bz2") == 0 )
+ unzipper = "bzcat" ;
+ else
+ unzipper = "" ;
+ } else if( strcmp(unzipper,"cat") == 0 )
+ unzipper = "" ;
+
+ if( *unzipper ) {
+ int pid, status, outfd ;
+#if HAVE_MMAP
+ xcfstream = tmpfile() ;
+ if( !xcfstream )
+ FatalUnexpected(_("!Cannot create temporary unzipped file"));
+ outfd = fileno(xcfstream) ;
+#else
+ int fh[2] ;
+ if( pipe(fh) < 0 )
+ FatalUnexpected("!Cannot create pipe for %s",unzipper);
+ xcfstream = fdopen(fh[1],"rb") ;
+ if( !xcfstream )
+ FatalUnexpected("!Cannot fdopen() unzipper pipe");
+ outfd = fh[0] ;
+#endif
+ if( (pid = fork()) == 0 ) {
+ /* We're the child */
+ if( dup2(outfd,1) < 0 ) {
+ perror("Cannot dup2 in unzip process");
+ exit(127) ;
+ }
+ fclose(xcfstream) ;
+ execlp(unzipper,unzipper,filename,NULL) ;
+ fprintf(stderr,_("Cannot execute "));
+ perror(unzipper);
+ exit(126) ;
+ }
+#if HAVE_MMAP
+ while( wait(&status) != pid )
+ ;
+ if( WIFEXITED(status) ) {
+ status = WEXITSTATUS(status) ;
+ if( status > 0 ) {
+ fclose(xcfstream) ;
+ xcfstream = 0 ;
+ FatalGeneric(status,NULL);
+ }
+ } else {
+ fclose(xcfstream) ;
+ xcfstream = 0 ;
+ FatalGeneric(126,_("%s terminated abnormally"),unzipper);
+ }
+#else
+ close(fh[0]) ;
+#endif
+ } else if( strcmp(filename,"-") == 0 ) {
+ xcfstream = fdopen(dup(0),"rb") ;
+ if( !xcfstream )
+ FatalUnexpected("!Cannot dup stdin for input") ;
+ } else {
+ xcfstream = fopen(filename,"rb") ;
+ if( !xcfstream )
+ FatalGeneric(21,_("!Cannot open %s"),filename);
+ }
+ /* OK, now we have an open stream ... */
+ if( fstat(fileno(xcfstream),&statbuf) == 0 &&
+ (statbuf.st_mode & S_IFMT) == S_IFREG ) {
+ xcf_length = statbuf.st_size ;
+#if HAVE_MMAP
+ xcf_file = mmap(0,xcf_length,PROT_READ,MAP_SHARED,fileno(xcfstream),0);
+ if( xcf_file != (void*)-1 )
+ return ;
+ if( errno != ENODEV ) {
+ int saved = errno ;
+ fclose(xcfstream) ;
+ xcf_file = 0 ;
+ errno = saved ;
+ FatalUnexpected("!Could not mmap input");
+ }
+#endif
+ xcf_file = malloc(xcf_length);
+ if( xcf_file == 0 )
+ FatalUnexpected(_("Out of memory for xcf data"));
+ if( fread(xcf_file,1,xcf_length,xcfstream) != xcf_length ) {
+ if( feof(xcfstream) )
+ FatalUnexpected(_("XCF file shrunk while reading it"));
+ else
+ FatalUnexpected(_("!Could not read xcf data"));
+ }
+ fclose(xcfstream) ;
+ xcfstream = 0 ;
+ } else {
+ size_t blocksize = 0x80000 ; /* 512 KB */
+ xcf_length = 0 ;
+ xcf_file = 0 ;
+ while(1) {
+ xcf_file = realloc(xcf_file,blocksize) ;
+ if( xcf_file == 0 )
+ FatalUnexpected(_("Out of memory for xcf data"));
+ size_t actual = fread(xcf_file+xcf_length,1,blocksize-xcf_length,
+ xcfstream) ;
+ xcf_length += actual ;
+ if( feof(xcfstream) )
+ break ;
+ if( xcf_length < blocksize ) {
+ FatalUnexpected(_("!Could not read xcf data")) ;
+ }
+ blocksize += (blocksize >> 1) & ~(size_t)0x3FFF ; /* 16 KB granularity */
+ }
+ fclose(xcfstream) ;
+ xcfstream = 0 ;
+ }
+}
diff --git a/kernel/kls_xcf/xcf2pnm/options.i b/kernel/kls_xcf/xcf2pnm/options.i
new file mode 100644
index 0000000..f891767
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/options.i
@@ -0,0 +1,410 @@
+/* Option processing for xcftools -*- C -*-
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+OPTIONGROUP(1i,General options);
+
+OPTION('h',--help,show this message,
+ (Print an option summery to standard output and exit with a
+ return code of 0.
+ ));
+exit(0);
+
+OPTION('V',--version,show version,
+ (Print the version numer of
+ .B xcftools
+ to standard output and exit with a return code of 0.
+ ));
+printf(OPTI_TARGET " - " PACKAGE_STRING "\n");
+exit(0);
+
+OPTION('v',--verbose,show progress messages,
+ (Print progress messages about the conversion to standard error.
+ ));
+verboseFlag = 1 ;
+break ;
+
+OPTION('j',--bzip,input is bzip2 compressed,
+ (Equivalent to
+ .BR "\-Z bzcat" .
+ Default if the filename ends with
+ .BR bz2 .
+ ));
+unzipper = "bzcat" ;
+break ;
+
+OPTION('z',--gzip,input is gzip compressed,
+ (Equivalent to
+ .BR "\-Z zcat" .
+ Default if the filename ends with
+ .BR gz .
+ ));
+unzipper = "zcat" ;
+break ;
+
+OPTION('Z',--unpack,(command) use 'command' to decompress input,
+ (Specify a command that the input file is filtered through
+ before being interpreted as an XCF file. The command is invoked as
+ .I command filename
+ and must produce output to its standard output.
+ Note that it is not possible to specify arguments as part of
+ .IR command .
+ An uncompressor is selected automatically if the filename ends
+ with
+ .B gz
+ or
+ .BR bz2 ;
+ to suppress this, use
+ .B \-Z cat
+ (which is implemented without actually starting a
+ .BR cat (1)
+ process).
+ ));
+unzipper = optarg ;
+break ;
+
+#ifdef XCF2FOO
+
+OPTION('o',--output,(filename) name output file,
+ (Write the converted picture to
+ .I filename
+ instead of to standard output.
+ ));
+flatspec.output_filename = optarg ;
+break ;
+
+#ifdef XCF2PNM
+OPTION('a',--alpha,(filename) write transparency map,
+ (Output a transparency mask for the flattened image to
+ .I filename
+ as a
+ .BR pgm (5)
+ file, in addition to the ordinary output.
+ If the flattened image is completely opaque, this will produce an
+ error message and exit status 101;
+ use
+ .B \-A
+ to suppress this.
+ ));
+flatspec.transmap_filename = optarg ;
+break ;
+#endif
+
+OPTION('b',--background,(color) select background color,
+ (Use this color for transparent pixels in the image.
+ The color can be given as
+ .B #rrggbb
+ or
+ .B #rgb
+ hexadecimal values,
+ or as an X11 color name
+ (which will only work if a color name database can be found
+ in one of a number of standard locations).
+ ));
+{
+ unsigned r,g,b ;
+ unsigned long hex ;
+ int met = 0 ;
+ if( *optarg == '#' )
+ sscanf(optarg+1,"%lx%n",&hex,&met);
+ if( met == 3 && strlen(optarg) == 4 ) {
+ r = ((hex >> 8) & 0xF) * 0x11 ;
+ g = ((hex >> 4) & 0xF) * 0x11 ;
+ b = ((hex >> 0) & 0xF) * 0x11 ;
+ } else if( met == 6 && strlen(optarg) == 7 ) {
+ r = ((hex >> 16) & 0xFF) ;
+ g = ((hex >> 8) & 0xFF) ;
+ b = ((hex >> 0) & 0xFF) ;
+ } else if( strcasecmp(optarg,"black") == 0 )
+ r = g = b = 0 ;
+ else if( strcasecmp(optarg,"white") == 0 )
+ r = g = b = 255 ;
+ else {
+ const char *filenames[] = { "/etc/X11/rgb.txt",
+ "/usr/lib/X11/rgb.txt",
+ "/usr/share/X11/rgb.txt",
+ NULL };
+ const char **fnp ;
+ r = (unsigned)-1 ;
+ int any = 0 ;
+ for( fnp = filenames; r == (unsigned)-1 && fnp && *fnp; fnp++ ) {
+ FILE *colortable = fopen(*fnp,"rt");
+ if( colortable ) {
+ any = 1 ;
+ int clen ;
+ char colorbuf[80] ;
+ do {
+ if( !fgets(colorbuf,sizeof colorbuf,colortable) ) {
+ r = (unsigned)-1 ;
+ break ;
+ }
+ clen = strlen(colorbuf);
+ while( clen && isspace(colorbuf[clen-1]) )
+ clen-- ;
+ colorbuf[clen] = '\0' ;
+ clen = 0 ;
+ sscanf(colorbuf," %u %u %u %n",&r,&g,&b,&clen);
+ } while( clen == 0 || strcasecmp(colorbuf+clen,optarg) != 0 );
+ fclose(colortable) ;
+ }
+ }
+ if( !any ) {
+ fprintf(stderr,_("Could not find X11 color database\n"));
+ }
+ }
+ if( r == (unsigned)-1 )
+ FatalGeneric(20,_("Unknown background color '%s'"),optarg);
+ flatspec.default_pixel = ((rgba)255 << ALPHA_SHIFT)
+ + ((rgba)r << RED_SHIFT)
+ + ((rgba)g << GREEN_SHIFT)
+ + ((rgba)b << BLUE_SHIFT);
+ break ;
+}
+
+OPTION('A',--force-alpha,force alpha channel in output,
+ (Invent a trivial alpha channel even if the flattened image is
+ completely opaque.
+ ));
+flatspec.default_pixel = FORCE_ALPHA_CHANNEL ;
+break ;
+
+OPTION('c',--color --colour,select color output,
+ (Force the output to use RGB color space even if it there are
+ more compact alternatives.
+#ifdef XCF2PNM
+ This will be selected automatically if the output file''s name
+ ends with
+ .BR .ppm .
+#endif
+ ));
+flatspec.out_color_mode = COLOR_RGB ;
+break ;
+
+OPTION('g',--gray --grey,select grayscale output,
+ (Force the output to be a grayscale image even if it may be monochrome.
+ If any colored pixels are encountered, exit with status 103.
+ This will be selected automatically if the output file''s name
+ ends with
+ .BR .pgm .
+ ));
+flatspec.out_color_mode = COLOR_GRAY ;
+break ;
+
+#ifdef XCF2PNM
+OPTION('m',--mono,select monochrome output,
+ (Force the output to be a monochrome image.
+ If any colors except black and white are encountered, exit with
+ status 103.
+ This will be selected automatically if the output file''s name
+ ends with
+ .BR .pbm .
+ ));
+flatspec.out_color_mode = COLOR_MONO ;
+break ;
+#endif
+
+#ifdef XCF2PNM
+OPTION('n',--pnm,select -c/-g/-m by image contents,
+ (Suppress the automatic choice of
+ .BR \-c ,
+ .BR \-g ,
+ or
+ .BR \-m
+ based on output filename, and instead select the output format
+ based on image contents.
+ This is the default if the filename is not recognized, and
+ when writing to stdout.
+ ));
+flatspec.out_color_mode = COLOR_BY_CONTENTS ;
+break ;
+#endif
+
+OPTION('T',--truecolor,treat indexed images as RGB for flattening,
+ (Use standard RGB compositing for flattening indexed layers.
+ Without this option,
+ .B \*p
+ will mimic the Gimp''s current strategy of rounding each
+ alpha value to either full transparency or full opacity,
+ and interpret all layer modes as
+ .BR Normal .
+ ));
+flatspec.gimpish_indexed = 0 ;
+break ;
+
+OPTION('G',--for-gif,disallow partial transparency,
+ (Assert that the flattened image will have no partial transparency
+ (allowing a more compact representation of the alpha output).
+ Exit with status 102 if the flattened image has any partial
+ transparency.
+ If
+ .B \-b
+ is also given, this tests whether there there is partial
+ transparency before applying the background color.
+ ));
+flatspec.partial_transparency_mode = FORBID_PARTIAL_TRANSPARENCY ;
+break ;
+
+OPTION('D',--dissolve,dissolve partial transparency,
+ (Do a "dissolve" step to eliminate partial transparency after
+ flattening.
+ If
+ .B \-b
+ is also given, this happens before the background color is applied.
+ ));
+flatspec.partial_transparency_mode = DISSOLVE_PARTIAL_TRANSPARENCY ;
+break ;
+
+OPTION('f',--full-image,flatten to memory; then analyse,
+ (First flatten the entire image to a memory buffer before writing
+ output. Then analyse the image to decide on the details of the
+ output format (e.g., whether a grayscale output is sufficient).
+ Without this option, the program flattens only a singe row of "tiles"
+ (height 64) at a time.
+ ));
+flatspec.process_in_memory = 1 ;
+break ;
+
+OPTION('S',--size,(w"x"h) crop image while converting,
+ (Crop the converted image to width \fIw\fP and height \fIh\fP.
+ ));
+{
+ unsigned w,h ;
+ int n = 0 ;
+ sscanf(optarg,"%ux%u%n",&w,&h,&n) ;
+ if( n && n == strlen(optarg) ) {
+ if( flatspec.window_mode == AUTOCROP ) flatspec.window_mode = USE_CANVAS ;
+ flatspec.window_mode |= MANUAL_CROP ;
+ flatspec.dim.width = w ;
+ flatspec.dim.height = h ;
+ } else
+ FatalGeneric(20,_("-S option must have an argument of the form wxh"));
+ break ;
+}
+
+OPTION('O',--offset,(x","y) translate converted part of image,
+ (Offset the converted part of the image from the top-left corner
+ of the XCF canvas. Usually used with
+ .BR \-S .
+ ));
+{
+ int x,y ;
+ int n = 0 ;
+ sscanf(optarg,"%d,%d%n",&x,&y,&n) ;
+ if( n && n == strlen(optarg) ) {
+ if( flatspec.window_mode == AUTOCROP ) flatspec.window_mode = USE_CANVAS ;
+ flatspec.window_mode |= MANUAL_OFFSET ;
+ flatspec.dim.c.l = x ;
+ flatspec.dim.c.t = y ;
+ } else
+ FatalGeneric(20,_("-O option must have an argument of the form x,y"));
+ break ;
+}
+
+OPTION('C',--autocrop,autocrop to visible layer boundaries,
+ (Crop and offset the converted part of the image to just include
+ the boundaries of the visible (or selected) layers.
+ (Note that the
+ .I contents
+ of the layers is not taken into account when autocropping).
+ .IP
+ In the absence of options that specify otherwise, the converted
+ image will cover the entire XCF canvas.
+ ));
+flatspec.window_mode = AUTOCROP ;
+break ;
+
+#ifndef XCFVIEW
+OPTIONGROUP(1il,Layer-selection options);
+#endif
+
+OPTION(300,--mode,(mode) set layer mode,
+ (Set the layer mode (e.g.,
+ .B Normal
+ or
+ .BR Multiply ).
+ ));
+{
+ GimpLayerModeEffects m ;
+ #ifdef ENABLE_NLS
+ for( m = 0; m < GimpLayerModeEffects_LAST; m++ )
+ if( strcmp(optarg,_(showGimpLayerModeEffects(m))) == 0 )
+ goto found_localized ;
+ #endif
+
+ for( m = 0; strcmp(optarg,showGimpLayerModeEffects(m)) != 0 ; m++ ) {
+ if( m > GimpLayerModeEffects_LAST )
+ FatalGeneric(20,_("Layer mode '%s' is unknown"),optarg);
+ }
+ found_localized:
+ lastlayerspec(&flatspec,"--mode")->mode = m ;
+ break ;
+}
+
+OPTION(301,--percent,(n) set opacity in percent,
+ (Set the opacity on a scale from 0 to 100
+ (as in the Gimp user interface).
+ ));
+{
+ unsigned pct ;
+ int n ;
+ sscanf(optarg,"%u%n",&pct,&n) ;
+ if( n != strlen(optarg) || pct > 100 )
+ FatalGeneric(20,_("The argument to --percent is not a percentage"));
+ lastlayerspec(&flatspec,"--percent")->opacity = pct * 255 / 100 ;
+ break ;
+}
+
+OPTION(302,--opacity,(n) set opacity in 1/255 units,
+ (Set the opacity on a scale from 0 to 255 (as used internally)
+ ));
+{
+ unsigned alpha ;
+ int n ;
+ sscanf(optarg,"%u%n",&alpha,&n) ;
+ if( n != strlen(optarg) || alpha > 255 )
+ FatalGeneric(20,_("The argument to --opacity is not a number "
+ "between 0 and 255"));
+ lastlayerspec(&flatspec,"--percent")->opacity = alpha ;
+ break ;
+}
+
+OPTION(303,--mask,enable layer mask,
+ (Enable the layer mask.
+ ));
+lastlayerspec(&flatspec,"--mask")->hasMask = 1 ;
+break ;
+
+OPTION(304,--nomask,disable layer mask,
+ (Disable the layer mask.
+ ));
+lastlayerspec(&flatspec,"--nomask")->hasMask = 0 ;
+break ;
+
+#endif /* XCF2FOO */
+
+OPTIONGROUP(1i,)
+
+#if HAVE_ICONV
+OPTION('u',--utf8,use UTF-8 for layer names,
+ (Use the raw UTF-8 representation from the XCF file to compare
+ and display layer names.
+ Ordinarily, layer names will be converted to the character set
+ of the current locale.
+ ));
+use_utf8 = 1 ;
+break ;
+#endif
diff --git a/kernel/kls_xcf/xcf2pnm/pixels.c b/kernel/kls_xcf/xcf2pnm/pixels.c
new file mode 100644
index 0000000..65891f9
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/pixels.c
@@ -0,0 +1,487 @@
+/* Pixel and tile functions for xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define DEBUG
+#include "xcftools.h"
+#include "pixels.h"
+#include <assert.h>
+#include <string.h>
+
+rgba colormap[256] ;
+unsigned colormapLength=0 ;
+
+int
+degrayPixel(rgba pixel)
+{
+ if( ((pixel >> RED_SHIFT) & 255) == ((pixel >> GREEN_SHIFT) & 255) &&
+ ((pixel >> RED_SHIFT) & 255) == ((pixel >> BLUE_SHIFT) & 255) )
+ return (pixel >> RED_SHIFT) & 255 ;
+ return -1 ;
+}
+
+/* ****************************************************************** */
+
+typedef const struct _convertParams {
+ int bpp ;
+ int shift[4] ;
+ uint32_t base_pixel ;
+ const rgba *lookup ;
+} convertParams ;
+#define RGB_SHIFT RED_SHIFT, GREEN_SHIFT, BLUE_SHIFT
+#define OPAQUE (255 << ALPHA_SHIFT)
+static convertParams convertRGB = { 3, {RGB_SHIFT}, OPAQUE, 0 };
+static convertParams convertRGBA = { 4, {RGB_SHIFT, ALPHA_SHIFT}, 0,0 };
+static convertParams convertGRAY = { 1, {-1}, OPAQUE, graytable };
+static convertParams convertGRAYA = { 2, {-1,ALPHA_SHIFT}, 0, graytable };
+static convertParams convertINDEXED = { 1, {-1}, OPAQUE, colormap };
+static convertParams convertINDEXEDA = { 2, {-1,ALPHA_SHIFT}, 0, colormap };
+
+static convertParams convertColormap = { 3, {RGB_SHIFT}, 0, 0 };
+static convertParams convertChannel = { 1, {ALPHA_SHIFT}, 0, 0 };
+
+/* ****************************************************************** */
+
+static inline int
+tileDirectoryOneLevel(struct tileDimensions *dim,uint32_t ptr)
+{
+ if( ptr == 0 )
+ return 0 ;
+ if( xcfL(ptr ) != dim->c.r - dim->c.l ||
+ xcfL(ptr+4) != dim->c.b - dim->c.t )
+ FatalBadXCF("Drawable size mismatch at %" PRIX32, ptr);
+ return ptr += 8 ;
+}
+
+static void
+initTileDirectory(struct tileDimensions *dim,struct xcfTiles *tiles,
+ const char *type)
+{
+ uint32_t ptr ;
+ uint32_t data ;
+
+ ptr = tiles->hierarchy ;
+ tiles->hierarchy = 0 ;
+ if( (ptr = tileDirectoryOneLevel(dim,ptr)) == 0 ) return ;
+ if( tiles->params == &convertChannel ) {
+ /* A layer mask is a channel.
+ * Skip a name and a property list.
+ */
+ xcfString(ptr,&ptr);
+ while( xcfNextprop(&ptr,&data) != PROP_END )
+ ;
+ ptr = xcfOffset(ptr,4*4);
+ if( (ptr = tileDirectoryOneLevel(dim,ptr)) == 0 ) return ;
+ }
+ /* The XCF format has a dummy "hierarchy" level which was
+ * once meant to mean something, but never happened. It contains
+ * the bpp value and a list of "level" pointers; but only the
+ * first level actually contains data.
+ */
+ data = xcfL(ptr) ;
+ if( xcfL(ptr) != tiles->params->bpp )
+ FatalBadXCF("%"PRIu32" bytes per pixel for %s drawable",xcfL(ptr),type);
+ ptr = xcfOffset(ptr+4,3*4) ;
+ if( (ptr = tileDirectoryOneLevel(dim,ptr)) == 0 ) return ;
+
+ xcfCheckspace(ptr,dim->ntiles*4+4,"Tile directory at %" PRIX32,ptr);
+ if( xcfL(ptr + dim->ntiles*4) != 0 )
+ FatalBadXCF("Wrong sized tile directory at %" PRIX32,ptr);
+#define REUSE_RAW_DATA tiles->tileptrs = (uint32_t*)(xcf_file + ptr)
+#if defined(WORDS_BIGENDIAN) && defined(CAN_DO_UNALIGNED_WORDS)
+ REUSE_RAW_DATA;
+#else
+# if defined(WORDS_BIGENDIAN)
+ if( (ptr&3) == 0 ) REUSE_RAW_DATA; else
+# endif
+ {
+ unsigned i ;
+ tiles->tileptrs = xcfmalloc(dim->ntiles * sizeof(uint32_t)) ;
+ for( i = 0 ; i < dim->ntiles ; i++ )
+ tiles->tileptrs[i] = xcfL(ptr+i*4);
+ }
+#endif
+}
+
+void
+initLayer(struct xcfLayer *layer) {
+ if( layer->dim.ntiles == 0 ||
+ (layer->pixels.hierarchy == 0 && layer->mask.hierarchy == 0) )
+ return ;
+ switch(layer->type) {
+#define DEF(X) case GIMP_##X##_IMAGE: layer->pixels.params = &convert##X; break
+ DEF(RGB);
+ DEF(RGBA);
+ DEF(GRAY);
+ DEF(GRAYA);
+ DEF(INDEXED);
+ DEF(INDEXEDA);
+ default:
+ FatalUnsupportedXCF(_("Layer type %s"),_(showGimpImageType(layer->type)));
+ }
+ initTileDirectory(&layer->dim,&layer->pixels,
+ _(showGimpImageType(layer->type)));
+ layer->mask.params = &convertChannel ;
+ initTileDirectory(&layer->dim,&layer->mask,"layer mask");
+}
+static void copyStraightPixels(rgba *dest,unsigned npixels,
+ uint32_t ptr,convertParams *params);
+void
+initColormap(void) {
+ uint32_t ncolors ;
+ if( XCF.colormapptr == 0 ) {
+ colormapLength = 0 ;
+ return ;
+ }
+ ncolors = xcfL(XCF.colormapptr) ;
+ if( ncolors > 256 )
+ FatalUnsupportedXCF(_("Color map has more than 256 entries"));
+ copyStraightPixels(colormap,ncolors,XCF.colormapptr+4,&convertColormap);
+ colormapLength = ncolors ;
+#ifdef xDEBUG
+ {
+ unsigned j ;
+ fprintf(stderr,"Colormap decoding OK\n");
+ for( j = 0 ; j < ncolors ; j++ ) {
+ if( j % 8 == 0 ) fprintf(stderr,"\n");
+ fprintf(stderr," %08x",colormap[j]);
+ }
+ fprintf(stderr,"\n");
+ }
+#endif
+}
+
+/* ****************************************************************** */
+
+struct Tile *
+newTile(struct rect r)
+{
+ unsigned npixels = (unsigned)(r.b-r.t) * (unsigned)(r.r-r.l) ;
+ struct Tile *data
+ = xcfmalloc(sizeof(struct Tile) -
+ sizeof(rgba)*(TILE_HEIGHT*TILE_WIDTH - npixels)) ;
+ data->count = npixels ;
+ data->refcount = 1 ;
+ data->summary = 0 ;
+ return data ;
+}
+
+struct Tile *
+forkTile(struct Tile* tile)
+{
+ if( ++tile->refcount <= 0 )
+ FatalUnsupportedXCF(_("Unbelievably many layers?\n"
+ "More likely to be a bug in %s"),progname);
+ return tile ;
+}
+
+void
+freeTile(struct Tile* tile)
+{
+ if( --tile->refcount == 0 )
+ xcffree(tile) ;
+}
+
+summary_t
+tileSummary(struct Tile *tile)
+{
+ unsigned i ;
+ summary_t summary ;
+ if( (tile->summary & TILESUMMARY_UPTODATE) != 0 )
+ return tile->summary ;
+ summary = TILESUMMARY_ALLNULL + TILESUMMARY_ALLFULL + TILESUMMARY_CRISP ;
+ for( i=0; summary && i<tile->count; i++ ) {
+ if( FULLALPHA(tile->pixels[i]) )
+ summary &= ~TILESUMMARY_ALLNULL ;
+ else if( NULLALPHA(tile->pixels[i]) )
+ summary &= ~TILESUMMARY_ALLFULL ;
+ else
+ summary = 0 ;
+ }
+ summary += TILESUMMARY_UPTODATE ;
+ tile->summary = summary ;
+ return summary ;
+}
+
+void
+fillTile(struct Tile *tile,rgba data)
+{
+ unsigned i ;
+ for( i = 0 ; i < tile->count ; i++ )
+ tile->pixels[i] = data ;
+ if( FULLALPHA(data) )
+ tile->summary = TILESUMMARY_UPTODATE+TILESUMMARY_ALLFULL+TILESUMMARY_CRISP;
+ else if (NULLALPHA(data) )
+ tile->summary = TILESUMMARY_UPTODATE+TILESUMMARY_ALLNULL+TILESUMMARY_CRISP;
+ else
+ tile->summary = TILESUMMARY_UPTODATE ;
+}
+
+/* ****************************************************************** */
+
+static void
+copyStraightPixels(rgba *dest,unsigned npixels,
+ uint32_t ptr,convertParams *params)
+{
+ unsigned bpp = params->bpp;
+ const rgba *lookup = params->lookup;
+ rgba base_pixel = params->base_pixel ;
+ uint8_t *bp = xcf_file + ptr ;
+ xcfCheckspace(ptr,bpp*npixels,
+ "pixel array (%u x %d bpp) at %"PRIX32,npixels,bpp,ptr);
+ while( npixels-- ) {
+ rgba pixel = base_pixel ;
+ unsigned i ;
+ for( i = 0 ; i < bpp ; i++ ) {
+ if( params->shift[i] < 0 ) {
+ pixel += lookup[*bp++] ;
+ } else {
+ pixel += *bp++ << params->shift[i] ;
+ }
+ }
+ *dest++ = pixel ;
+ }
+}
+
+static inline void
+copyRLEpixels(rgba *dest,unsigned npixels,uint32_t ptr,convertParams *params)
+{
+ unsigned i,j ;
+ rgba base_pixel = params->base_pixel ;
+
+#ifdef xDEBUG
+ fprintf(stderr,"RLE stream at %x, want %u x %u pixels, base %x\n",
+ ptr,params->bpp,npixels,base_pixel);
+#endif
+
+
+ /* This algorithm depends on the indexed byte always being the first one */
+ if( params->shift[0] < -1 )
+ base_pixel = 0 ;
+ for( j = npixels ; j-- ; )
+ dest[j] = base_pixel ;
+
+ for( i = 0 ; i < params->bpp ; i++ ) {
+ int shift = params->shift[i] ;
+ if( shift < 0 )
+ shift = 0 ;
+ for( j = 0 ; j < npixels ; ) {
+ int countspec ;
+ unsigned count ;
+ xcfCheckspace(ptr,2,"RLE data stream");
+ countspec = (int8_t) xcf_file[ptr++] ;
+ count = countspec >= 0 ? countspec+1 : -countspec ;
+ if( count == 128 ) {
+ xcfCheckspace(ptr,3,"RLE long count");
+ count = xcf_file[ptr++] << 8 ;
+ count += xcf_file[ptr++] ;
+ }
+ if( j + count > npixels )
+ FatalBadXCF("Overlong RLE run at %"PRIX32" (plane %u, %u left)",
+ ptr,i,npixels-j);
+ if( countspec >= 0 ) {
+ rgba data = (uint32_t) xcf_file[ptr++] << shift ;
+ while( count-- )
+ dest[j++] += data ;
+ } else {
+ while( count-- )
+ dest[j++] += (uint32_t) xcf_file[ptr++] << shift ;
+ }
+ }
+ if( i == 0 && params->shift[0] < 0 ) {
+ const rgba *lookup = params->lookup ;
+ base_pixel = params->base_pixel ;
+ for( j = npixels ; j-- ; ) {
+ dest[j] = lookup[dest[j]-base_pixel] + base_pixel ;
+ }
+ }
+ }
+#ifdef xDEBUG
+ fprintf(stderr,"RLE decoding OK at %"PRIX32"\n",ptr);
+ /*
+ for( j = 0 ; j < npixels ; j++ ) {
+ if( j % 8 == 0 ) fprintf(stderr,"\n");
+ fprintf(stderr," %8x",dest[j]);
+ }
+ fprintf(stderr,"\n");
+ */
+#endif
+}
+
+static inline void
+copyTilePixels(struct Tile *dest, uint32_t ptr,convertParams *params)
+{
+ if( FULLALPHA(params->base_pixel) )
+ dest->summary = TILESUMMARY_UPTODATE+TILESUMMARY_ALLFULL+TILESUMMARY_CRISP;
+ else
+ dest->summary = 0 ;
+ switch( XCF.compression ) {
+ case COMPRESS_NONE:
+ copyStraightPixels(dest->pixels,dest->count,ptr,params);
+ break ;
+ case COMPRESS_RLE:
+ copyRLEpixels(dest->pixels,dest->count,ptr,params);
+ break ;
+ default:
+ FatalUnsupportedXCF(_("%s compression"),
+ _(showXcfCompressionType(XCF.compression)));
+ }
+}
+
+static struct Tile *
+getMaskOrLayerTile(struct tileDimensions *dim, struct xcfTiles *tiles,
+ struct rect want)
+{
+ struct Tile *tile = newTile(want);
+
+ assert( want.l < want.r && want.t < want.b );
+ if( tiles->tileptrs == 0 ) {
+ fillTile(tile,0);
+ return tile ;
+ }
+
+#ifdef xDEBUG
+ fprintf(stderr,"getMaskOrLayer: (%d-%d),(%d-%d)\n",left,right,top,bottom);
+#endif
+
+ if( isSubrect(want,dim->c) &&
+ (want.l - dim->c.l) % TILE_WIDTH == 0 &&
+ (want.t - dim->c.t) % TILE_HEIGHT == 0 ) {
+ unsigned tx = (want.l - dim->c.l) / TILE_WIDTH ;
+ unsigned ty = (want.t - dim->c.t) / TILE_WIDTH ;
+ if( want.r == TILEXn(*dim,tx+1) && want.b == TILEYn(*dim,ty+1) ) {
+ /* The common case? An entire single tile from the layer */
+ copyTilePixels(tile,tiles->tileptrs[tx + ty*dim->tilesx],tiles->params);
+ return tile ;
+ }
+ }
+
+ /* OK, we must construct the wanted tile as a jigsaw */
+ {
+ unsigned width = want.r-want.l ;
+ rgba *pixvert = tile->pixels ;
+ rgba *pixhoriz ;
+ unsigned y, ty, l0, l1, lstart, lnum ;
+ unsigned x, tx, c0, c1, cstart, cnum ;
+
+ if( !isSubrect(want,dim->c) ) {
+ if( want.l < dim->c.l ) pixvert += (dim->c.l - want.l),
+ want.l = dim->c.l ;
+ if( want.r > dim->c.r ) want.r = dim->c.r ;
+ if( want.t < dim->c.t ) pixvert += (dim->c.t - want.t) * width,
+ want.t = dim->c.t ;
+ if( want.b > dim->c.b ) want.b = dim->c.b ;
+ fillTile(tile,0);
+ } else {
+ tile->summary = -1 ; /* I.e. whatever the jigsaw pieces say */
+ }
+
+#ifdef xDEBUG
+ fprintf(stderr,"jig0 (%d-%d),(%d-%d)\n",left,right,top,bottom);
+#endif
+
+ for( y=want.t, ty=(want.t-dim->c.t)/TILE_HEIGHT, l0=TILEYn(*dim,ty);
+ y<want.b;
+ pixvert += lnum*width, ty++, y=l0=l1 ) {
+ l1 = TILEYn(*dim,ty+1) ;
+ lstart = y - l0 ;
+ lnum = (l1 > want.b ? want.b : l1) - y ;
+
+ pixhoriz = pixvert ;
+ for( x=want.l, tx=(want.l-dim->c.l)/TILE_WIDTH, c0=TILEXn(*dim,tx);
+ x<want.r;
+ pixhoriz += cnum, tx++, x=c0=c1 ) {
+ c1 = TILEXn(*dim,tx+1);
+ cstart = x - c0 ;
+ cnum = (c1 > want.r ? want.r : c1) - x ;
+
+ {
+ static struct Tile tmptile ;
+ unsigned dwidth = c1-c0 ;
+ unsigned i, j ;
+ tmptile.count = (c1-c0)*(l1-l0) ;
+#ifdef xDEBUG
+ fprintf(stderr,"jig ty=%u(%u-%u-%u)(%u+%u) tx=%u(%u-%u-%u)(%u+%u)\n",
+ ty,l0,y,l1,lstart,lnum,
+ tx,c0,x,c1,cstart,cnum);
+#endif
+ copyTilePixels(&tmptile,
+ tiles->tileptrs[tx+ty*dim->tilesx],tiles->params);
+ for(i=0; i<lnum; i++)
+ for(j=0; j<cnum; j++)
+ pixhoriz[i*width+j]
+ = tmptile.pixels[(i+lstart)*dwidth+(j+cstart)];
+ tile->summary &= tmptile.summary ;
+ }
+ }
+ }
+ }
+ return tile ;
+}
+
+void
+applyMask(struct Tile *tile, struct Tile *mask)
+{
+ unsigned i ;
+ assertTileCompatibility(tile,mask);
+ assert( tile->count == mask->count );
+ INIT_SCALETABLE_IF(1);
+ invalidateSummary(tile,0);
+ for( i=0; i < tile->count ;i++ )
+ tile->pixels[i] = NEWALPHA(tile->pixels[i],
+ scaletable[mask->pixels[i]>>ALPHA_SHIFT]
+ [ALPHA(tile->pixels[i])]);
+ freeTile(mask);
+}
+
+struct Tile *
+getLayerTile(struct xcfLayer *layer,const struct rect *where)
+{
+ struct Tile *data ;
+
+#ifdef xDEBUG
+ fprintf(stderr,"getLayerTile(%s): (%d-%d),(%d-%d)\n",
+ layer->name,where->l,where->r,where->t,where->b);
+#endif
+
+ if( disjointRects(*where,layer->dim.c) ||
+ layer->opacity == 0 ) {
+ data = newTile(*where);
+ fillTile(data,0);
+ return data ;
+ }
+
+ data = getMaskOrLayerTile(&layer->dim,&layer->pixels,*where);
+ if( (data->summary & TILESUMMARY_ALLNULL) != 0 )
+ return data ;
+ if( layer->hasMask ) {
+ struct Tile *mask = getMaskOrLayerTile(&layer->dim,&layer->mask,*where);
+ applyMask(data,mask);
+ }
+ if( layer->opacity < 255 ) {
+ const uint8_t *ourtable ;
+ int i ;
+ invalidateSummary(data,~(TILESUMMARY_CRISP | TILESUMMARY_ALLFULL));
+ INIT_SCALETABLE_IF(1);
+ ourtable = scaletable[layer->opacity] ;
+ for( i=0; i < data->count; i++ )
+ data->pixels[i]
+ = NEWALPHA(data->pixels[i],ourtable[ALPHA(data->pixels[i])]) ;
+ }
+ return data ;
+}
+
diff --git a/kernel/kls_xcf/xcf2pnm/pixels.h b/kernel/kls_xcf/xcf2pnm/pixels.h
new file mode 100644
index 0000000..1ee5219
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/pixels.h
@@ -0,0 +1,128 @@
+/* Pixel and tile functions for xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef PIXELS_H
+#define PIXELS_H
+
+#include "xcftools.h"
+
+/* MACROS FOR INTERNAL PIXEL ORDERING HERE */
+/*=========================================*/
+/* In principle the internal representation of pixels may change.
+ * - this was supposed to allow an optimization where a layer could
+ * be represented as a pointer into the mmapped xcf file, if
+ * alignment, bpp, and endianness agreed (the point was that the
+ * pixel representation had to agree with the endianness).
+ *
+ * However, it turns out that the current Gimp _always_ saves images
+ * with RLE encoding of tiles, so such an effort would be in vain.
+ *
+ * Just for modularity, nevertheless try to isolate knowledge of
+ * the RGBA-to-machine-word packing in this section of the
+ * header file. Define new macros if necessary.
+ *
+ * Given that we don't have to agree with the uncompressed
+ * RLE format, we choose to have the alpha in the _least_
+ * significant byte on all archs - it is tested and used more
+ * often than the visible channels.
+ */
+typedef uint32_t rgba ;
+
+#define ALPHA_SHIFT 0
+#define RED_SHIFT 8
+#define GREEN_SHIFT 16
+#define BLUE_SHIFT 24
+
+#define ALPHA(rgba) ((uint8_t)(rgba))
+#define FULLALPHA(rgba) ((uint8_t)(rgba) == 255)
+#define NULLALPHA(rgba) ((uint8_t)(rgba) == 0)
+#define NEWALPHA(rgb,a) (((rgba)(rgb) & 0xFFFFFF00) + (a))
+
+#ifdef PRECOMPUTED_SCALETABLE
+extern const uint8_t scaletable[256][256] ;
+#define INIT_SCALETABLE_IF(foo) ((void)0)
+#else
+extern uint8_t scaletable[256][256] ;
+extern int ok_scaletable ;
+void mk_scaletable(void);
+#define INIT_SCALETABLE_IF(foo) \
+ (ok_scaletable || !(foo) || (mk_scaletable(),0) )
+#endif
+
+extern const rgba graytable[256] ;
+extern rgba colormap[256] ;
+extern unsigned colormapLength ;
+void initLayer(struct xcfLayer *);
+void initColormap();
+
+int degrayPixel(rgba); /* returns -1 for non-gray pixels */
+
+/* ******************************************************* */
+
+#define TILEXn(dim,tx) \
+ ((tx)==(dim).tilesx ? (dim).c.r : (dim).c.l + ((tx)*TILE_WIDTH))
+#define TILEYn(dim,ty) \
+ ((ty)==(dim).tilesy ? (dim).c.b : (dim).c.t + ((ty)*TILE_HEIGHT))
+
+#if __i386__
+/* This is probably the only common architecture where small constants
+ * are more efficient for byte operations.
+ */
+typedef int8_t summary_t ;
+typedef short int refcount_t ;
+#else
+typedef int summary_t ;
+typedef int refcount_t ;
+#endif
+
+#define TILESUMMARY_UPTODATE 8
+#define TILESUMMARY_ALLNULL 4
+#define TILESUMMARY_ALLFULL 2
+#define TILESUMMARY_CRISP 1 /* everyting either null or full */
+struct Tile {
+ refcount_t refcount ;
+ summary_t summary ; /* a combination of TIMESUMMARY_FOO constatns */
+ unsigned count ;
+ rgba pixels[TILE_WIDTH * TILE_HEIGHT];
+};
+/* Actually, the Tile structures that get allocated many not have
+ * room for that many pixels. We subtract the space for those we don't
+ * use - which is Not Legal C, but ought to be portable.
+ * OTOH, one can also use a static struct Tile for temporary storage.
+ */
+
+
+#define assertTileCompatibility(t1,t2) assert((t1)->count==(t2)->count)
+
+struct Tile *newTile(struct rect);
+struct Tile *forkTile(struct Tile*);
+void freeTile(struct Tile*);
+#define invalidateSummary(tile,mask) \
+ do{ assert((tile)->refcount==1); (tile)->summary &= mask; } while(0)
+summary_t __ATTRIBUTE__((pure)) tileSummary(struct Tile *);
+
+void fillTile(struct Tile*,rgba);
+
+/* applyMask() destructively changes tile,
+ * applyMask() gets ownership of mask
+ */
+void applyMask(struct Tile *tile, struct Tile *mask);
+
+struct Tile *getLayerTile(struct xcfLayer *,const struct rect *);
+
+#endif /* FLATTEN_H */
diff --git a/kernel/kls_xcf/xcf2pnm/scaletab.c b/kernel/kls_xcf/xcf2pnm/scaletab.c
new file mode 100644
index 0000000..c09867e
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/scaletab.c
@@ -0,0 +1,42 @@
+/* Run-time scaletable computation for Xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "pixels.h"
+#ifndef PRECOMPUTED_SCALETABLE
+
+uint8_t scaletable[256][256] ;
+int ok_scaletable = 0 ;
+
+void
+mk_scaletable(void)
+{
+ unsigned p, q, r ;
+ if( ok_scaletable ) return ;
+ for( p = 0 ; p < 128 ; p++ )
+ for( q = 0 ; q <= p ; q++ ) {
+ r = (p*q+127)/255 ;
+ scaletable[p][q] = scaletable[q][p] = r ;
+ scaletable[255-p][q] = scaletable[q][255-p] = q-r ;
+ scaletable[p][255-q] = scaletable[255-q][p] = p-r ;
+ scaletable[255-p][255-q] = scaletable[255-q][255-p] = (255-q)-(p-r) ;
+ }
+ ok_scaletable = 1 ;
+}
+
+#endif
+
diff --git a/kernel/kls_xcf/xcf2pnm/table.c b/kernel/kls_xcf/xcf2pnm/table.c
new file mode 100644
index 0000000..9e76923
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/table.c
@@ -0,0 +1,263 @@
+/* Autogenerated by mktablec.pl */
+#include "pixels.h"
+#ifdef PRECOMPUTED_SCALETABLE
+#error PRECOMPUTED_SCALETABLE was not defined at generation time
+#endif
+const rgba graytable[256] = {
+ (rgba)0 << RED_SHIFT | (rgba)0 << GREEN_SHIFT | (rgba)0 << BLUE_SHIFT,
+ (rgba)1 << RED_SHIFT | (rgba)1 << GREEN_SHIFT | (rgba)1 << BLUE_SHIFT,
+ (rgba)2 << RED_SHIFT | (rgba)2 << GREEN_SHIFT | (rgba)2 << BLUE_SHIFT,
+ (rgba)3 << RED_SHIFT | (rgba)3 << GREEN_SHIFT | (rgba)3 << BLUE_SHIFT,
+ (rgba)4 << RED_SHIFT | (rgba)4 << GREEN_SHIFT | (rgba)4 << BLUE_SHIFT,
+ (rgba)5 << RED_SHIFT | (rgba)5 << GREEN_SHIFT | (rgba)5 << BLUE_SHIFT,
+ (rgba)6 << RED_SHIFT | (rgba)6 << GREEN_SHIFT | (rgba)6 << BLUE_SHIFT,
+ (rgba)7 << RED_SHIFT | (rgba)7 << GREEN_SHIFT | (rgba)7 << BLUE_SHIFT,
+ (rgba)8 << RED_SHIFT | (rgba)8 << GREEN_SHIFT | (rgba)8 << BLUE_SHIFT,
+ (rgba)9 << RED_SHIFT | (rgba)9 << GREEN_SHIFT | (rgba)9 << BLUE_SHIFT,
+ (rgba)10 << RED_SHIFT | (rgba)10 << GREEN_SHIFT | (rgba)10 << BLUE_SHIFT,
+ (rgba)11 << RED_SHIFT | (rgba)11 << GREEN_SHIFT | (rgba)11 << BLUE_SHIFT,
+ (rgba)12 << RED_SHIFT | (rgba)12 << GREEN_SHIFT | (rgba)12 << BLUE_SHIFT,
+ (rgba)13 << RED_SHIFT | (rgba)13 << GREEN_SHIFT | (rgba)13 << BLUE_SHIFT,
+ (rgba)14 << RED_SHIFT | (rgba)14 << GREEN_SHIFT | (rgba)14 << BLUE_SHIFT,
+ (rgba)15 << RED_SHIFT | (rgba)15 << GREEN_SHIFT | (rgba)15 << BLUE_SHIFT,
+ (rgba)16 << RED_SHIFT | (rgba)16 << GREEN_SHIFT | (rgba)16 << BLUE_SHIFT,
+ (rgba)17 << RED_SHIFT | (rgba)17 << GREEN_SHIFT | (rgba)17 << BLUE_SHIFT,
+ (rgba)18 << RED_SHIFT | (rgba)18 << GREEN_SHIFT | (rgba)18 << BLUE_SHIFT,
+ (rgba)19 << RED_SHIFT | (rgba)19 << GREEN_SHIFT | (rgba)19 << BLUE_SHIFT,
+ (rgba)20 << RED_SHIFT | (rgba)20 << GREEN_SHIFT | (rgba)20 << BLUE_SHIFT,
+ (rgba)21 << RED_SHIFT | (rgba)21 << GREEN_SHIFT | (rgba)21 << BLUE_SHIFT,
+ (rgba)22 << RED_SHIFT | (rgba)22 << GREEN_SHIFT | (rgba)22 << BLUE_SHIFT,
+ (rgba)23 << RED_SHIFT | (rgba)23 << GREEN_SHIFT | (rgba)23 << BLUE_SHIFT,
+ (rgba)24 << RED_SHIFT | (rgba)24 << GREEN_SHIFT | (rgba)24 << BLUE_SHIFT,
+ (rgba)25 << RED_SHIFT | (rgba)25 << GREEN_SHIFT | (rgba)25 << BLUE_SHIFT,
+ (rgba)26 << RED_SHIFT | (rgba)26 << GREEN_SHIFT | (rgba)26 << BLUE_SHIFT,
+ (rgba)27 << RED_SHIFT | (rgba)27 << GREEN_SHIFT | (rgba)27 << BLUE_SHIFT,
+ (rgba)28 << RED_SHIFT | (rgba)28 << GREEN_SHIFT | (rgba)28 << BLUE_SHIFT,
+ (rgba)29 << RED_SHIFT | (rgba)29 << GREEN_SHIFT | (rgba)29 << BLUE_SHIFT,
+ (rgba)30 << RED_SHIFT | (rgba)30 << GREEN_SHIFT | (rgba)30 << BLUE_SHIFT,
+ (rgba)31 << RED_SHIFT | (rgba)31 << GREEN_SHIFT | (rgba)31 << BLUE_SHIFT,
+ (rgba)32 << RED_SHIFT | (rgba)32 << GREEN_SHIFT | (rgba)32 << BLUE_SHIFT,
+ (rgba)33 << RED_SHIFT | (rgba)33 << GREEN_SHIFT | (rgba)33 << BLUE_SHIFT,
+ (rgba)34 << RED_SHIFT | (rgba)34 << GREEN_SHIFT | (rgba)34 << BLUE_SHIFT,
+ (rgba)35 << RED_SHIFT | (rgba)35 << GREEN_SHIFT | (rgba)35 << BLUE_SHIFT,
+ (rgba)36 << RED_SHIFT | (rgba)36 << GREEN_SHIFT | (rgba)36 << BLUE_SHIFT,
+ (rgba)37 << RED_SHIFT | (rgba)37 << GREEN_SHIFT | (rgba)37 << BLUE_SHIFT,
+ (rgba)38 << RED_SHIFT | (rgba)38 << GREEN_SHIFT | (rgba)38 << BLUE_SHIFT,
+ (rgba)39 << RED_SHIFT | (rgba)39 << GREEN_SHIFT | (rgba)39 << BLUE_SHIFT,
+ (rgba)40 << RED_SHIFT | (rgba)40 << GREEN_SHIFT | (rgba)40 << BLUE_SHIFT,
+ (rgba)41 << RED_SHIFT | (rgba)41 << GREEN_SHIFT | (rgba)41 << BLUE_SHIFT,
+ (rgba)42 << RED_SHIFT | (rgba)42 << GREEN_SHIFT | (rgba)42 << BLUE_SHIFT,
+ (rgba)43 << RED_SHIFT | (rgba)43 << GREEN_SHIFT | (rgba)43 << BLUE_SHIFT,
+ (rgba)44 << RED_SHIFT | (rgba)44 << GREEN_SHIFT | (rgba)44 << BLUE_SHIFT,
+ (rgba)45 << RED_SHIFT | (rgba)45 << GREEN_SHIFT | (rgba)45 << BLUE_SHIFT,
+ (rgba)46 << RED_SHIFT | (rgba)46 << GREEN_SHIFT | (rgba)46 << BLUE_SHIFT,
+ (rgba)47 << RED_SHIFT | (rgba)47 << GREEN_SHIFT | (rgba)47 << BLUE_SHIFT,
+ (rgba)48 << RED_SHIFT | (rgba)48 << GREEN_SHIFT | (rgba)48 << BLUE_SHIFT,
+ (rgba)49 << RED_SHIFT | (rgba)49 << GREEN_SHIFT | (rgba)49 << BLUE_SHIFT,
+ (rgba)50 << RED_SHIFT | (rgba)50 << GREEN_SHIFT | (rgba)50 << BLUE_SHIFT,
+ (rgba)51 << RED_SHIFT | (rgba)51 << GREEN_SHIFT | (rgba)51 << BLUE_SHIFT,
+ (rgba)52 << RED_SHIFT | (rgba)52 << GREEN_SHIFT | (rgba)52 << BLUE_SHIFT,
+ (rgba)53 << RED_SHIFT | (rgba)53 << GREEN_SHIFT | (rgba)53 << BLUE_SHIFT,
+ (rgba)54 << RED_SHIFT | (rgba)54 << GREEN_SHIFT | (rgba)54 << BLUE_SHIFT,
+ (rgba)55 << RED_SHIFT | (rgba)55 << GREEN_SHIFT | (rgba)55 << BLUE_SHIFT,
+ (rgba)56 << RED_SHIFT | (rgba)56 << GREEN_SHIFT | (rgba)56 << BLUE_SHIFT,
+ (rgba)57 << RED_SHIFT | (rgba)57 << GREEN_SHIFT | (rgba)57 << BLUE_SHIFT,
+ (rgba)58 << RED_SHIFT | (rgba)58 << GREEN_SHIFT | (rgba)58 << BLUE_SHIFT,
+ (rgba)59 << RED_SHIFT | (rgba)59 << GREEN_SHIFT | (rgba)59 << BLUE_SHIFT,
+ (rgba)60 << RED_SHIFT | (rgba)60 << GREEN_SHIFT | (rgba)60 << BLUE_SHIFT,
+ (rgba)61 << RED_SHIFT | (rgba)61 << GREEN_SHIFT | (rgba)61 << BLUE_SHIFT,
+ (rgba)62 << RED_SHIFT | (rgba)62 << GREEN_SHIFT | (rgba)62 << BLUE_SHIFT,
+ (rgba)63 << RED_SHIFT | (rgba)63 << GREEN_SHIFT | (rgba)63 << BLUE_SHIFT,
+ (rgba)64 << RED_SHIFT | (rgba)64 << GREEN_SHIFT | (rgba)64 << BLUE_SHIFT,
+ (rgba)65 << RED_SHIFT | (rgba)65 << GREEN_SHIFT | (rgba)65 << BLUE_SHIFT,
+ (rgba)66 << RED_SHIFT | (rgba)66 << GREEN_SHIFT | (rgba)66 << BLUE_SHIFT,
+ (rgba)67 << RED_SHIFT | (rgba)67 << GREEN_SHIFT | (rgba)67 << BLUE_SHIFT,
+ (rgba)68 << RED_SHIFT | (rgba)68 << GREEN_SHIFT | (rgba)68 << BLUE_SHIFT,
+ (rgba)69 << RED_SHIFT | (rgba)69 << GREEN_SHIFT | (rgba)69 << BLUE_SHIFT,
+ (rgba)70 << RED_SHIFT | (rgba)70 << GREEN_SHIFT | (rgba)70 << BLUE_SHIFT,
+ (rgba)71 << RED_SHIFT | (rgba)71 << GREEN_SHIFT | (rgba)71 << BLUE_SHIFT,
+ (rgba)72 << RED_SHIFT | (rgba)72 << GREEN_SHIFT | (rgba)72 << BLUE_SHIFT,
+ (rgba)73 << RED_SHIFT | (rgba)73 << GREEN_SHIFT | (rgba)73 << BLUE_SHIFT,
+ (rgba)74 << RED_SHIFT | (rgba)74 << GREEN_SHIFT | (rgba)74 << BLUE_SHIFT,
+ (rgba)75 << RED_SHIFT | (rgba)75 << GREEN_SHIFT | (rgba)75 << BLUE_SHIFT,
+ (rgba)76 << RED_SHIFT | (rgba)76 << GREEN_SHIFT | (rgba)76 << BLUE_SHIFT,
+ (rgba)77 << RED_SHIFT | (rgba)77 << GREEN_SHIFT | (rgba)77 << BLUE_SHIFT,
+ (rgba)78 << RED_SHIFT | (rgba)78 << GREEN_SHIFT | (rgba)78 << BLUE_SHIFT,
+ (rgba)79 << RED_SHIFT | (rgba)79 << GREEN_SHIFT | (rgba)79 << BLUE_SHIFT,
+ (rgba)80 << RED_SHIFT | (rgba)80 << GREEN_SHIFT | (rgba)80 << BLUE_SHIFT,
+ (rgba)81 << RED_SHIFT | (rgba)81 << GREEN_SHIFT | (rgba)81 << BLUE_SHIFT,
+ (rgba)82 << RED_SHIFT | (rgba)82 << GREEN_SHIFT | (rgba)82 << BLUE_SHIFT,
+ (rgba)83 << RED_SHIFT | (rgba)83 << GREEN_SHIFT | (rgba)83 << BLUE_SHIFT,
+ (rgba)84 << RED_SHIFT | (rgba)84 << GREEN_SHIFT | (rgba)84 << BLUE_SHIFT,
+ (rgba)85 << RED_SHIFT | (rgba)85 << GREEN_SHIFT | (rgba)85 << BLUE_SHIFT,
+ (rgba)86 << RED_SHIFT | (rgba)86 << GREEN_SHIFT | (rgba)86 << BLUE_SHIFT,
+ (rgba)87 << RED_SHIFT | (rgba)87 << GREEN_SHIFT | (rgba)87 << BLUE_SHIFT,
+ (rgba)88 << RED_SHIFT | (rgba)88 << GREEN_SHIFT | (rgba)88 << BLUE_SHIFT,
+ (rgba)89 << RED_SHIFT | (rgba)89 << GREEN_SHIFT | (rgba)89 << BLUE_SHIFT,
+ (rgba)90 << RED_SHIFT | (rgba)90 << GREEN_SHIFT | (rgba)90 << BLUE_SHIFT,
+ (rgba)91 << RED_SHIFT | (rgba)91 << GREEN_SHIFT | (rgba)91 << BLUE_SHIFT,
+ (rgba)92 << RED_SHIFT | (rgba)92 << GREEN_SHIFT | (rgba)92 << BLUE_SHIFT,
+ (rgba)93 << RED_SHIFT | (rgba)93 << GREEN_SHIFT | (rgba)93 << BLUE_SHIFT,
+ (rgba)94 << RED_SHIFT | (rgba)94 << GREEN_SHIFT | (rgba)94 << BLUE_SHIFT,
+ (rgba)95 << RED_SHIFT | (rgba)95 << GREEN_SHIFT | (rgba)95 << BLUE_SHIFT,
+ (rgba)96 << RED_SHIFT | (rgba)96 << GREEN_SHIFT | (rgba)96 << BLUE_SHIFT,
+ (rgba)97 << RED_SHIFT | (rgba)97 << GREEN_SHIFT | (rgba)97 << BLUE_SHIFT,
+ (rgba)98 << RED_SHIFT | (rgba)98 << GREEN_SHIFT | (rgba)98 << BLUE_SHIFT,
+ (rgba)99 << RED_SHIFT | (rgba)99 << GREEN_SHIFT | (rgba)99 << BLUE_SHIFT,
+ (rgba)100 << RED_SHIFT | (rgba)100 << GREEN_SHIFT | (rgba)100 << BLUE_SHIFT,
+ (rgba)101 << RED_SHIFT | (rgba)101 << GREEN_SHIFT | (rgba)101 << BLUE_SHIFT,
+ (rgba)102 << RED_SHIFT | (rgba)102 << GREEN_SHIFT | (rgba)102 << BLUE_SHIFT,
+ (rgba)103 << RED_SHIFT | (rgba)103 << GREEN_SHIFT | (rgba)103 << BLUE_SHIFT,
+ (rgba)104 << RED_SHIFT | (rgba)104 << GREEN_SHIFT | (rgba)104 << BLUE_SHIFT,
+ (rgba)105 << RED_SHIFT | (rgba)105 << GREEN_SHIFT | (rgba)105 << BLUE_SHIFT,
+ (rgba)106 << RED_SHIFT | (rgba)106 << GREEN_SHIFT | (rgba)106 << BLUE_SHIFT,
+ (rgba)107 << RED_SHIFT | (rgba)107 << GREEN_SHIFT | (rgba)107 << BLUE_SHIFT,
+ (rgba)108 << RED_SHIFT | (rgba)108 << GREEN_SHIFT | (rgba)108 << BLUE_SHIFT,
+ (rgba)109 << RED_SHIFT | (rgba)109 << GREEN_SHIFT | (rgba)109 << BLUE_SHIFT,
+ (rgba)110 << RED_SHIFT | (rgba)110 << GREEN_SHIFT | (rgba)110 << BLUE_SHIFT,
+ (rgba)111 << RED_SHIFT | (rgba)111 << GREEN_SHIFT | (rgba)111 << BLUE_SHIFT,
+ (rgba)112 << RED_SHIFT | (rgba)112 << GREEN_SHIFT | (rgba)112 << BLUE_SHIFT,
+ (rgba)113 << RED_SHIFT | (rgba)113 << GREEN_SHIFT | (rgba)113 << BLUE_SHIFT,
+ (rgba)114 << RED_SHIFT | (rgba)114 << GREEN_SHIFT | (rgba)114 << BLUE_SHIFT,
+ (rgba)115 << RED_SHIFT | (rgba)115 << GREEN_SHIFT | (rgba)115 << BLUE_SHIFT,
+ (rgba)116 << RED_SHIFT | (rgba)116 << GREEN_SHIFT | (rgba)116 << BLUE_SHIFT,
+ (rgba)117 << RED_SHIFT | (rgba)117 << GREEN_SHIFT | (rgba)117 << BLUE_SHIFT,
+ (rgba)118 << RED_SHIFT | (rgba)118 << GREEN_SHIFT | (rgba)118 << BLUE_SHIFT,
+ (rgba)119 << RED_SHIFT | (rgba)119 << GREEN_SHIFT | (rgba)119 << BLUE_SHIFT,
+ (rgba)120 << RED_SHIFT | (rgba)120 << GREEN_SHIFT | (rgba)120 << BLUE_SHIFT,
+ (rgba)121 << RED_SHIFT | (rgba)121 << GREEN_SHIFT | (rgba)121 << BLUE_SHIFT,
+ (rgba)122 << RED_SHIFT | (rgba)122 << GREEN_SHIFT | (rgba)122 << BLUE_SHIFT,
+ (rgba)123 << RED_SHIFT | (rgba)123 << GREEN_SHIFT | (rgba)123 << BLUE_SHIFT,
+ (rgba)124 << RED_SHIFT | (rgba)124 << GREEN_SHIFT | (rgba)124 << BLUE_SHIFT,
+ (rgba)125 << RED_SHIFT | (rgba)125 << GREEN_SHIFT | (rgba)125 << BLUE_SHIFT,
+ (rgba)126 << RED_SHIFT | (rgba)126 << GREEN_SHIFT | (rgba)126 << BLUE_SHIFT,
+ (rgba)127 << RED_SHIFT | (rgba)127 << GREEN_SHIFT | (rgba)127 << BLUE_SHIFT,
+ (rgba)128 << RED_SHIFT | (rgba)128 << GREEN_SHIFT | (rgba)128 << BLUE_SHIFT,
+ (rgba)129 << RED_SHIFT | (rgba)129 << GREEN_SHIFT | (rgba)129 << BLUE_SHIFT,
+ (rgba)130 << RED_SHIFT | (rgba)130 << GREEN_SHIFT | (rgba)130 << BLUE_SHIFT,
+ (rgba)131 << RED_SHIFT | (rgba)131 << GREEN_SHIFT | (rgba)131 << BLUE_SHIFT,
+ (rgba)132 << RED_SHIFT | (rgba)132 << GREEN_SHIFT | (rgba)132 << BLUE_SHIFT,
+ (rgba)133 << RED_SHIFT | (rgba)133 << GREEN_SHIFT | (rgba)133 << BLUE_SHIFT,
+ (rgba)134 << RED_SHIFT | (rgba)134 << GREEN_SHIFT | (rgba)134 << BLUE_SHIFT,
+ (rgba)135 << RED_SHIFT | (rgba)135 << GREEN_SHIFT | (rgba)135 << BLUE_SHIFT,
+ (rgba)136 << RED_SHIFT | (rgba)136 << GREEN_SHIFT | (rgba)136 << BLUE_SHIFT,
+ (rgba)137 << RED_SHIFT | (rgba)137 << GREEN_SHIFT | (rgba)137 << BLUE_SHIFT,
+ (rgba)138 << RED_SHIFT | (rgba)138 << GREEN_SHIFT | (rgba)138 << BLUE_SHIFT,
+ (rgba)139 << RED_SHIFT | (rgba)139 << GREEN_SHIFT | (rgba)139 << BLUE_SHIFT,
+ (rgba)140 << RED_SHIFT | (rgba)140 << GREEN_SHIFT | (rgba)140 << BLUE_SHIFT,
+ (rgba)141 << RED_SHIFT | (rgba)141 << GREEN_SHIFT | (rgba)141 << BLUE_SHIFT,
+ (rgba)142 << RED_SHIFT | (rgba)142 << GREEN_SHIFT | (rgba)142 << BLUE_SHIFT,
+ (rgba)143 << RED_SHIFT | (rgba)143 << GREEN_SHIFT | (rgba)143 << BLUE_SHIFT,
+ (rgba)144 << RED_SHIFT | (rgba)144 << GREEN_SHIFT | (rgba)144 << BLUE_SHIFT,
+ (rgba)145 << RED_SHIFT | (rgba)145 << GREEN_SHIFT | (rgba)145 << BLUE_SHIFT,
+ (rgba)146 << RED_SHIFT | (rgba)146 << GREEN_SHIFT | (rgba)146 << BLUE_SHIFT,
+ (rgba)147 << RED_SHIFT | (rgba)147 << GREEN_SHIFT | (rgba)147 << BLUE_SHIFT,
+ (rgba)148 << RED_SHIFT | (rgba)148 << GREEN_SHIFT | (rgba)148 << BLUE_SHIFT,
+ (rgba)149 << RED_SHIFT | (rgba)149 << GREEN_SHIFT | (rgba)149 << BLUE_SHIFT,
+ (rgba)150 << RED_SHIFT | (rgba)150 << GREEN_SHIFT | (rgba)150 << BLUE_SHIFT,
+ (rgba)151 << RED_SHIFT | (rgba)151 << GREEN_SHIFT | (rgba)151 << BLUE_SHIFT,
+ (rgba)152 << RED_SHIFT | (rgba)152 << GREEN_SHIFT | (rgba)152 << BLUE_SHIFT,
+ (rgba)153 << RED_SHIFT | (rgba)153 << GREEN_SHIFT | (rgba)153 << BLUE_SHIFT,
+ (rgba)154 << RED_SHIFT | (rgba)154 << GREEN_SHIFT | (rgba)154 << BLUE_SHIFT,
+ (rgba)155 << RED_SHIFT | (rgba)155 << GREEN_SHIFT | (rgba)155 << BLUE_SHIFT,
+ (rgba)156 << RED_SHIFT | (rgba)156 << GREEN_SHIFT | (rgba)156 << BLUE_SHIFT,
+ (rgba)157 << RED_SHIFT | (rgba)157 << GREEN_SHIFT | (rgba)157 << BLUE_SHIFT,
+ (rgba)158 << RED_SHIFT | (rgba)158 << GREEN_SHIFT | (rgba)158 << BLUE_SHIFT,
+ (rgba)159 << RED_SHIFT | (rgba)159 << GREEN_SHIFT | (rgba)159 << BLUE_SHIFT,
+ (rgba)160 << RED_SHIFT | (rgba)160 << GREEN_SHIFT | (rgba)160 << BLUE_SHIFT,
+ (rgba)161 << RED_SHIFT | (rgba)161 << GREEN_SHIFT | (rgba)161 << BLUE_SHIFT,
+ (rgba)162 << RED_SHIFT | (rgba)162 << GREEN_SHIFT | (rgba)162 << BLUE_SHIFT,
+ (rgba)163 << RED_SHIFT | (rgba)163 << GREEN_SHIFT | (rgba)163 << BLUE_SHIFT,
+ (rgba)164 << RED_SHIFT | (rgba)164 << GREEN_SHIFT | (rgba)164 << BLUE_SHIFT,
+ (rgba)165 << RED_SHIFT | (rgba)165 << GREEN_SHIFT | (rgba)165 << BLUE_SHIFT,
+ (rgba)166 << RED_SHIFT | (rgba)166 << GREEN_SHIFT | (rgba)166 << BLUE_SHIFT,
+ (rgba)167 << RED_SHIFT | (rgba)167 << GREEN_SHIFT | (rgba)167 << BLUE_SHIFT,
+ (rgba)168 << RED_SHIFT | (rgba)168 << GREEN_SHIFT | (rgba)168 << BLUE_SHIFT,
+ (rgba)169 << RED_SHIFT | (rgba)169 << GREEN_SHIFT | (rgba)169 << BLUE_SHIFT,
+ (rgba)170 << RED_SHIFT | (rgba)170 << GREEN_SHIFT | (rgba)170 << BLUE_SHIFT,
+ (rgba)171 << RED_SHIFT | (rgba)171 << GREEN_SHIFT | (rgba)171 << BLUE_SHIFT,
+ (rgba)172 << RED_SHIFT | (rgba)172 << GREEN_SHIFT | (rgba)172 << BLUE_SHIFT,
+ (rgba)173 << RED_SHIFT | (rgba)173 << GREEN_SHIFT | (rgba)173 << BLUE_SHIFT,
+ (rgba)174 << RED_SHIFT | (rgba)174 << GREEN_SHIFT | (rgba)174 << BLUE_SHIFT,
+ (rgba)175 << RED_SHIFT | (rgba)175 << GREEN_SHIFT | (rgba)175 << BLUE_SHIFT,
+ (rgba)176 << RED_SHIFT | (rgba)176 << GREEN_SHIFT | (rgba)176 << BLUE_SHIFT,
+ (rgba)177 << RED_SHIFT | (rgba)177 << GREEN_SHIFT | (rgba)177 << BLUE_SHIFT,
+ (rgba)178 << RED_SHIFT | (rgba)178 << GREEN_SHIFT | (rgba)178 << BLUE_SHIFT,
+ (rgba)179 << RED_SHIFT | (rgba)179 << GREEN_SHIFT | (rgba)179 << BLUE_SHIFT,
+ (rgba)180 << RED_SHIFT | (rgba)180 << GREEN_SHIFT | (rgba)180 << BLUE_SHIFT,
+ (rgba)181 << RED_SHIFT | (rgba)181 << GREEN_SHIFT | (rgba)181 << BLUE_SHIFT,
+ (rgba)182 << RED_SHIFT | (rgba)182 << GREEN_SHIFT | (rgba)182 << BLUE_SHIFT,
+ (rgba)183 << RED_SHIFT | (rgba)183 << GREEN_SHIFT | (rgba)183 << BLUE_SHIFT,
+ (rgba)184 << RED_SHIFT | (rgba)184 << GREEN_SHIFT | (rgba)184 << BLUE_SHIFT,
+ (rgba)185 << RED_SHIFT | (rgba)185 << GREEN_SHIFT | (rgba)185 << BLUE_SHIFT,
+ (rgba)186 << RED_SHIFT | (rgba)186 << GREEN_SHIFT | (rgba)186 << BLUE_SHIFT,
+ (rgba)187 << RED_SHIFT | (rgba)187 << GREEN_SHIFT | (rgba)187 << BLUE_SHIFT,
+ (rgba)188 << RED_SHIFT | (rgba)188 << GREEN_SHIFT | (rgba)188 << BLUE_SHIFT,
+ (rgba)189 << RED_SHIFT | (rgba)189 << GREEN_SHIFT | (rgba)189 << BLUE_SHIFT,
+ (rgba)190 << RED_SHIFT | (rgba)190 << GREEN_SHIFT | (rgba)190 << BLUE_SHIFT,
+ (rgba)191 << RED_SHIFT | (rgba)191 << GREEN_SHIFT | (rgba)191 << BLUE_SHIFT,
+ (rgba)192 << RED_SHIFT | (rgba)192 << GREEN_SHIFT | (rgba)192 << BLUE_SHIFT,
+ (rgba)193 << RED_SHIFT | (rgba)193 << GREEN_SHIFT | (rgba)193 << BLUE_SHIFT,
+ (rgba)194 << RED_SHIFT | (rgba)194 << GREEN_SHIFT | (rgba)194 << BLUE_SHIFT,
+ (rgba)195 << RED_SHIFT | (rgba)195 << GREEN_SHIFT | (rgba)195 << BLUE_SHIFT,
+ (rgba)196 << RED_SHIFT | (rgba)196 << GREEN_SHIFT | (rgba)196 << BLUE_SHIFT,
+ (rgba)197 << RED_SHIFT | (rgba)197 << GREEN_SHIFT | (rgba)197 << BLUE_SHIFT,
+ (rgba)198 << RED_SHIFT | (rgba)198 << GREEN_SHIFT | (rgba)198 << BLUE_SHIFT,
+ (rgba)199 << RED_SHIFT | (rgba)199 << GREEN_SHIFT | (rgba)199 << BLUE_SHIFT,
+ (rgba)200 << RED_SHIFT | (rgba)200 << GREEN_SHIFT | (rgba)200 << BLUE_SHIFT,
+ (rgba)201 << RED_SHIFT | (rgba)201 << GREEN_SHIFT | (rgba)201 << BLUE_SHIFT,
+ (rgba)202 << RED_SHIFT | (rgba)202 << GREEN_SHIFT | (rgba)202 << BLUE_SHIFT,
+ (rgba)203 << RED_SHIFT | (rgba)203 << GREEN_SHIFT | (rgba)203 << BLUE_SHIFT,
+ (rgba)204 << RED_SHIFT | (rgba)204 << GREEN_SHIFT | (rgba)204 << BLUE_SHIFT,
+ (rgba)205 << RED_SHIFT | (rgba)205 << GREEN_SHIFT | (rgba)205 << BLUE_SHIFT,
+ (rgba)206 << RED_SHIFT | (rgba)206 << GREEN_SHIFT | (rgba)206 << BLUE_SHIFT,
+ (rgba)207 << RED_SHIFT | (rgba)207 << GREEN_SHIFT | (rgba)207 << BLUE_SHIFT,
+ (rgba)208 << RED_SHIFT | (rgba)208 << GREEN_SHIFT | (rgba)208 << BLUE_SHIFT,
+ (rgba)209 << RED_SHIFT | (rgba)209 << GREEN_SHIFT | (rgba)209 << BLUE_SHIFT,
+ (rgba)210 << RED_SHIFT | (rgba)210 << GREEN_SHIFT | (rgba)210 << BLUE_SHIFT,
+ (rgba)211 << RED_SHIFT | (rgba)211 << GREEN_SHIFT | (rgba)211 << BLUE_SHIFT,
+ (rgba)212 << RED_SHIFT | (rgba)212 << GREEN_SHIFT | (rgba)212 << BLUE_SHIFT,
+ (rgba)213 << RED_SHIFT | (rgba)213 << GREEN_SHIFT | (rgba)213 << BLUE_SHIFT,
+ (rgba)214 << RED_SHIFT | (rgba)214 << GREEN_SHIFT | (rgba)214 << BLUE_SHIFT,
+ (rgba)215 << RED_SHIFT | (rgba)215 << GREEN_SHIFT | (rgba)215 << BLUE_SHIFT,
+ (rgba)216 << RED_SHIFT | (rgba)216 << GREEN_SHIFT | (rgba)216 << BLUE_SHIFT,
+ (rgba)217 << RED_SHIFT | (rgba)217 << GREEN_SHIFT | (rgba)217 << BLUE_SHIFT,
+ (rgba)218 << RED_SHIFT | (rgba)218 << GREEN_SHIFT | (rgba)218 << BLUE_SHIFT,
+ (rgba)219 << RED_SHIFT | (rgba)219 << GREEN_SHIFT | (rgba)219 << BLUE_SHIFT,
+ (rgba)220 << RED_SHIFT | (rgba)220 << GREEN_SHIFT | (rgba)220 << BLUE_SHIFT,
+ (rgba)221 << RED_SHIFT | (rgba)221 << GREEN_SHIFT | (rgba)221 << BLUE_SHIFT,
+ (rgba)222 << RED_SHIFT | (rgba)222 << GREEN_SHIFT | (rgba)222 << BLUE_SHIFT,
+ (rgba)223 << RED_SHIFT | (rgba)223 << GREEN_SHIFT | (rgba)223 << BLUE_SHIFT,
+ (rgba)224 << RED_SHIFT | (rgba)224 << GREEN_SHIFT | (rgba)224 << BLUE_SHIFT,
+ (rgba)225 << RED_SHIFT | (rgba)225 << GREEN_SHIFT | (rgba)225 << BLUE_SHIFT,
+ (rgba)226 << RED_SHIFT | (rgba)226 << GREEN_SHIFT | (rgba)226 << BLUE_SHIFT,
+ (rgba)227 << RED_SHIFT | (rgba)227 << GREEN_SHIFT | (rgba)227 << BLUE_SHIFT,
+ (rgba)228 << RED_SHIFT | (rgba)228 << GREEN_SHIFT | (rgba)228 << BLUE_SHIFT,
+ (rgba)229 << RED_SHIFT | (rgba)229 << GREEN_SHIFT | (rgba)229 << BLUE_SHIFT,
+ (rgba)230 << RED_SHIFT | (rgba)230 << GREEN_SHIFT | (rgba)230 << BLUE_SHIFT,
+ (rgba)231 << RED_SHIFT | (rgba)231 << GREEN_SHIFT | (rgba)231 << BLUE_SHIFT,
+ (rgba)232 << RED_SHIFT | (rgba)232 << GREEN_SHIFT | (rgba)232 << BLUE_SHIFT,
+ (rgba)233 << RED_SHIFT | (rgba)233 << GREEN_SHIFT | (rgba)233 << BLUE_SHIFT,
+ (rgba)234 << RED_SHIFT | (rgba)234 << GREEN_SHIFT | (rgba)234 << BLUE_SHIFT,
+ (rgba)235 << RED_SHIFT | (rgba)235 << GREEN_SHIFT | (rgba)235 << BLUE_SHIFT,
+ (rgba)236 << RED_SHIFT | (rgba)236 << GREEN_SHIFT | (rgba)236 << BLUE_SHIFT,
+ (rgba)237 << RED_SHIFT | (rgba)237 << GREEN_SHIFT | (rgba)237 << BLUE_SHIFT,
+ (rgba)238 << RED_SHIFT | (rgba)238 << GREEN_SHIFT | (rgba)238 << BLUE_SHIFT,
+ (rgba)239 << RED_SHIFT | (rgba)239 << GREEN_SHIFT | (rgba)239 << BLUE_SHIFT,
+ (rgba)240 << RED_SHIFT | (rgba)240 << GREEN_SHIFT | (rgba)240 << BLUE_SHIFT,
+ (rgba)241 << RED_SHIFT | (rgba)241 << GREEN_SHIFT | (rgba)241 << BLUE_SHIFT,
+ (rgba)242 << RED_SHIFT | (rgba)242 << GREEN_SHIFT | (rgba)242 << BLUE_SHIFT,
+ (rgba)243 << RED_SHIFT | (rgba)243 << GREEN_SHIFT | (rgba)243 << BLUE_SHIFT,
+ (rgba)244 << RED_SHIFT | (rgba)244 << GREEN_SHIFT | (rgba)244 << BLUE_SHIFT,
+ (rgba)245 << RED_SHIFT | (rgba)245 << GREEN_SHIFT | (rgba)245 << BLUE_SHIFT,
+ (rgba)246 << RED_SHIFT | (rgba)246 << GREEN_SHIFT | (rgba)246 << BLUE_SHIFT,
+ (rgba)247 << RED_SHIFT | (rgba)247 << GREEN_SHIFT | (rgba)247 << BLUE_SHIFT,
+ (rgba)248 << RED_SHIFT | (rgba)248 << GREEN_SHIFT | (rgba)248 << BLUE_SHIFT,
+ (rgba)249 << RED_SHIFT | (rgba)249 << GREEN_SHIFT | (rgba)249 << BLUE_SHIFT,
+ (rgba)250 << RED_SHIFT | (rgba)250 << GREEN_SHIFT | (rgba)250 << BLUE_SHIFT,
+ (rgba)251 << RED_SHIFT | (rgba)251 << GREEN_SHIFT | (rgba)251 << BLUE_SHIFT,
+ (rgba)252 << RED_SHIFT | (rgba)252 << GREEN_SHIFT | (rgba)252 << BLUE_SHIFT,
+ (rgba)253 << RED_SHIFT | (rgba)253 << GREEN_SHIFT | (rgba)253 << BLUE_SHIFT,
+ (rgba)254 << RED_SHIFT | (rgba)254 << GREEN_SHIFT | (rgba)254 << BLUE_SHIFT,
+ (rgba)255 << RED_SHIFT | (rgba)255 << GREEN_SHIFT | (rgba)255 << BLUE_SHIFT,
+};
diff --git a/kernel/kls_xcf/xcf2pnm/utils.c b/kernel/kls_xcf/xcf2pnm/utils.c
new file mode 100644
index 0000000..bde0782
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/utils.c
@@ -0,0 +1,164 @@
+/* Generic support functions for Xcftools
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xcftools.h"
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+
+const char *progname = "$0" ;
+int verboseFlag = 0 ;
+
+
+static void __ATTRIBUTE__((noreturn))
+vFatalGeneric(int status,const char *format,va_list args)
+{
+ if( format ) {
+ if( *format == '!' ) {
+ vfprintf(stderr,format+1,args);
+ fprintf(stderr,": %s\n",strerror(errno));
+ } else {
+ vfprintf(stderr,format,args);
+ fputc('\n',stderr);
+ }
+ }
+ exit(status);
+}
+
+void
+FatalGeneric(int status,const char* format,...)
+{
+ va_list v; va_start(v,format);
+ if( format ) fprintf(stderr,"%s: ",progname);
+ vFatalGeneric(status,format,v);
+}
+
+void
+FatalUnexpected(const char* format,...)
+{
+ va_list v; va_start(v,format);
+ fprintf(stderr,"%s: ",progname);
+ vFatalGeneric(127,format,v) ;
+}
+
+void
+FatalBadXCF(const char* format,...)
+{
+ va_list v; va_start(v,format);
+ fprintf(stderr,"%s: %s:\n ",progname,_("Corrupted or malformed XCF file"));
+ vFatalGeneric(125,format,v) ;
+}
+
+void
+xcfCheckspace(uint32_t addr,int spaceafter,const char *format,...)
+{
+ if( xcf_length < spaceafter || addr > xcf_length - spaceafter ) {
+ va_list v; va_start(v,format);
+ fprintf(stderr,"%s: %s\n ",progname,_("Corrupted or truncated XCF file"));
+ fprintf(stderr,"(0x%" PRIXPTR " bytes): ",(uintptr_t)xcf_length);
+ vFatalGeneric(125,format,v) ;
+ }
+}
+
+
+void
+FatalUnsupportedXCF(const char* format,...)
+{
+ va_list v; va_start(v,format);
+ fprintf(stderr,"%s: %s\n ",progname,
+ _("The image contains features not understood by this program:"));
+ vFatalGeneric(123,format,v) ;
+}
+
+void
+gpl_blurb(void)
+{
+ fprintf(stderr,PACKAGE_STRING "\n");
+ fprintf(stderr,
+ _("This program is free software; you can modify and distribute it\n"
+ "under the terms of the GNU General Public License, version 2.\n"
+ "There is no warranty for %s.\n\n"),
+ PACKAGE_NAME);
+ fprintf(stderr,
+ _("Type \"%s -h\" to get an option summary.\n"),progname);
+ exit(1) ;
+}
+
+/* ******************************************************* */
+
+void *
+xcfmalloc(size_t size)
+{
+ void *ptr = malloc(size);
+ if( !ptr )
+ FatalUnexpected(_("Out of memory"));
+ return ptr ;
+}
+
+void
+xcffree(void *block)
+{
+ if( xcf_file &&
+ (uint8_t*)block >= xcf_file &&
+ (uint8_t*)block < xcf_file + xcf_length )
+ ;
+ else
+ free(block);
+}
+
+/* ******************************************************* */
+
+FILE *
+openout(const char *name)
+{
+ FILE *newfile ;
+ if( strcmp(name,"-") == 0 )
+ return stdout ;
+ newfile = fopen(name,"wb") ;
+ if( newfile == NULL )
+ FatalUnexpected(_("!Cannot create file %s"),name);
+ return newfile ;
+}
+
+void
+closeout(FILE *f,const char *name)
+{
+ if( f == NULL )
+ return ;
+ if( fflush(f) == 0 ) {
+ errno = 0 ;
+ if( !ferror(f) ) {
+ if( fclose(f) == 0 )
+ return ;
+ } else if( errno == 0 ) {
+ /* Attempt to coax a valid errno out of the standard library,
+ * following an idea by Bruno Haible
+ * http://lists.gnu.org/archive/html/bug-gnulib/2003-09/msg00157.html
+ */
+ if( fputc('\0', f) != EOF &&
+ fflush(f) == 0 )
+ errno = EIO ; /* Argh, everything succeds. Just call it an I/O error */
+ }
+ }
+ FatalUnexpected(_("!Error writing file %s"),name);
+}
+
+
+
+
diff --git a/kernel/kls_xcf/xcf2pnm/xcf-general.c b/kernel/kls_xcf/xcf2pnm/xcf-general.c
new file mode 100644
index 0000000..9231134
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/xcf-general.c
@@ -0,0 +1,287 @@
+/* Generic functions for reading XCF files
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xcftools.h"
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_ICONV
+# include <iconv.h>
+#elif !defined(ICONV_CONST)
+# define ICONV_CONST const
+#endif
+
+uint8_t *xcf_file = 0 ;
+size_t xcf_length ;
+int use_utf8 = 0 ;
+
+uint32_t
+xcfOffset(uint32_t addr,int spaceafter)
+{
+ uint32_t apparent ;
+ xcfCheckspace(addr,4,"(xcfOffset)");
+ apparent = xcfL(addr);
+ xcfCheckspace(apparent,spaceafter,
+ "Too large offset (%" PRIX32 ") at position %" PRIX32,
+ apparent,addr);
+ return apparent ;
+}
+
+int
+xcfNextprop(uint32_t *master,uint32_t *body)
+{
+ uint32_t ptr, length, total, minlength ;
+ PropType type ;
+ ptr = *master ;
+ xcfCheckspace(ptr,8,"(property header)");
+ type = xcfL(ptr);
+ length = xcfL(ptr+4);
+ *body = ptr+8 ;
+
+ switch(type) {
+ case PROP_COLORMAP:
+ {
+ uint32_t ncolors ;
+ xcfCheckspace(ptr+8,4,"(colormap length)");
+ ncolors = xcfL(ptr+8) ;
+ if( ncolors > 256 )
+ FatalBadXCF("Colormap has %" PRIu32 " entries",ncolors);
+ /* Surprise! Some older verion of the Gimp computed the wrong length
+ * word, and the _reader_ always just reads three bytes per color
+ * and ignores the length tag! Duplicate this so we too can read
+ * the buggy XCF files.
+ */
+ length = minlength = 4+3*ncolors;
+ break;
+ }
+ case PROP_COMPRESSION: minlength = 1; break;
+ case PROP_OPACITY: minlength = 4; break;
+ case PROP_APPLY_MASK: minlength = 4; break;
+ case PROP_OFFSETS: minlength = 8; break;
+ case PROP_MODE: minlength = 4; break;
+ default: minlength = 0; break;
+ }
+ if( length < minlength )
+ FatalBadXCF("Short %s property at %" PRIX32 " (%" PRIu32 "<%" PRIu32 ")",
+ showPropType(type),ptr,length,minlength);
+ *master = ptr+8+length ;
+ total = 8 + length + (type != PROP_END ? 8 : 0) ;
+ if( total < length ) /* Check overwrap */
+ FatalBadXCF("Overlong property at %" PRIX32, ptr);
+ xcfCheckspace(ptr,total,"Overlong property at %" PRIX32,ptr) ;
+ return type ;
+}
+
+const char*
+xcfString(uint32_t ptr,uint32_t *after)
+{
+ uint32_t length ;
+ unsigned i ;
+ ICONV_CONST char *utf8master ;
+
+ xcfCheckspace(ptr,4,"(string length)");
+ length = xcfL(ptr) ;
+ ptr += 4 ;
+ xcfCheckspace(ptr,length,"(string)");
+ utf8master = (ICONV_CONST char*)(xcf_file+ptr) ;
+ if( after ) *after = ptr + length ;
+ if( length == 0 || utf8master[length-1] != 0 )
+ FatalBadXCF("String at %" PRIX32 " not zero-terminated",ptr-4);
+ length-- ;
+
+ if( use_utf8 ) return utf8master ;
+
+ /* We assume that the local character set includes ASCII...
+ * Check if conversion is needed at all
+ */
+ for( i=0 ; ; i++ ) {
+ if( i == length )
+ return utf8master ; /* Only ASCII after all */
+ if( utf8master[i] == 0 )
+ FatalBadXCF("String at %" PRIX32 " has embedded zeroes",ptr-4);
+ if( (int8_t) utf8master[i] < 0 )
+ break ;
+ }
+#ifdef HAVE_ICONV
+ {
+ size_t targetsize = length+1 ;
+ int sloppy_translation = 0 ;
+ iconv_t cd = iconv_open("//TRANSLIT","UTF-8");
+ if( cd == (iconv_t) -1 ) {
+ cd = iconv_open("","UTF-8");
+ sloppy_translation = 1 ;
+ }
+ if( cd == (iconv_t) -1 )
+ iconv_close(cd) ; /* Give up; perhaps iconv doesn't know UTF-8 */
+ else
+ while(1) {
+ char *buffer = xcfmalloc(targetsize) ;
+ ICONV_CONST char *inbuf = utf8master ;
+ char *outbuf = buffer ;
+ size_t incount = length ;
+ size_t outcount = targetsize ;
+ while(1) { /* Loop for systems without //ICONV support */
+ size_t result = iconv(cd,&inbuf,&incount,&outbuf,&outcount) ;
+ if( result == (size_t)-1 && errno == EILSEQ &&
+ sloppy_translation && outcount > 0 ) {
+ *outbuf++ = '?' ;
+ outcount-- ;
+ while( (int8_t)*inbuf < 0 ) inbuf++, incount-- ;
+ continue ;
+ }
+ if( result != (size_t)-1 ) {
+ if( outcount == 0 )
+ errno = E2BIG ;
+ else {
+ *outbuf = 0 ;
+ iconv_close(cd) ;
+ return buffer ;
+ }
+ }
+ break ;
+ }
+ if( errno == EILSEQ || errno == EINVAL )
+ FatalBadXCF("Bad UTF-8 encoding '%s' at %" PRIXPTR,
+ inbuf,(uintptr_t)((inbuf-utf8master)+ptr));
+ if( errno == E2BIG ) {
+ targetsize += 1+incount ;
+ xcffree(buffer) ;
+ continue ;
+ }
+ FatalUnexpected("!iconv on layer name at %"PRIX32,ptr);
+ }
+ }
+#endif
+ {
+ static int warned = 0 ;
+ if( !warned ) {
+ fprintf(stderr,_("Warning: one or more layer names could not be\n"
+ " translated to the local character set.\n"));
+ warned = 1 ;
+ }
+ }
+ return utf8master ;
+}
+
+/* ****************************************************************** */
+
+void
+computeDimensions(struct tileDimensions *d)
+{
+ d->c.r = d->c.l + d->width ;
+ d->c.b = d->c.t + d->height ;
+ d->tilesx = (d->width+TILE_WIDTH-1)/TILE_WIDTH ;
+ d->tilesy = (d->height+TILE_HEIGHT-1)/TILE_HEIGHT ;
+ d->ntiles = d->tilesx * d->tilesy ;
+}
+
+struct xcfImage XCF ;
+
+void
+getBasicXcfInfo(void)
+{
+ uint32_t ptr, data, layerfile ;
+ PropType type ;
+ int i ;
+
+ xcfCheckspace(0,14+7*4,"(very short)");
+ if( strcmp((char*)xcf_file,"gimp xcf file") == 0 )
+ XCF.version = 0 ;
+ else if( xcf_file[13] == 0 &&
+ sscanf((char*)xcf_file,"gimp xcf v%d",&XCF.version) == 1 )
+ ;
+ else
+ FatalBadXCF(_("Not an XCF file at all (magic not recognized)"));
+
+ if( XCF.version < 0 || XCF.version > 2 ) {
+ fprintf(stderr,
+ _("Warning: XCF version %d not supported (trying anyway...)\n"),
+ XCF.version);
+ }
+
+ XCF.compression = COMPRESS_NONE ;
+ XCF.colormapptr = 0 ;
+
+ ptr = 14 ;
+ XCF.width = xcfL(ptr); ptr += 4 ;
+ XCF.height = xcfL(ptr); ptr += 4 ;
+ XCF.type = xcfL(ptr); ptr += 4 ;
+ while( (type = xcfNextprop(&ptr,&data)) != PROP_END ) {
+ switch(type) {
+ case PROP_COLORMAP:
+ XCF.colormapptr = data ;
+ break ;
+ case PROP_COMPRESSION:
+ XCF.compression = xcf_file[data] ;
+ break ;
+ default:
+ /* Ignore unknown properties */
+ break ;
+ }
+ }
+
+ layerfile = ptr ;
+ for( XCF.numLayers = 0 ; xcfOffset(ptr,8*4) ; XCF.numLayers++, ptr+=4 )
+ ;
+ XCF.layers = xcfmalloc(XCF.numLayers * sizeof(struct xcfLayer)) ;
+ for( i = 0 ; i < XCF.numLayers ; i++ ) {
+ struct xcfLayer *L = XCF.layers + i ;
+ ptr = xcfL(layerfile+4*(XCF.numLayers-1-i)) ;
+ L->mode = GIMP_NORMAL_MODE ;
+ L->opacity = 255 ;
+ L->isVisible = 1 ;
+ L->hasMask = 0 ;
+ L->dim.width = xcfL(ptr); ptr+=4 ;
+ L->dim.height = xcfL(ptr); ptr+=4 ;
+ L->type = xcfL(ptr); ptr+=4 ;
+ L->name = xcfString(ptr,&ptr);
+ L->propptr = ptr ;
+ while( (type = xcfNextprop(&ptr,&data)) != PROP_END ) {
+ switch(type) {
+ case PROP_OPACITY:
+ L->opacity = xcfL(data);
+ if( L->opacity > 255 )
+ L->opacity = 255 ;
+ break ;
+ case PROP_VISIBLE:
+ L->isVisible = xcfL(data) != 0 ;
+ break ;
+ case PROP_APPLY_MASK:
+ L->hasMask = xcfL(data) != 0 ;
+ break ;
+ case PROP_OFFSETS:
+ L->dim.c.l = (int32_t)(xcfL(data )) ;
+ L->dim.c.t = (int32_t)(xcfL(data+4)) ;
+ break ;
+ case PROP_MODE:
+ L->mode = xcfL(data);
+ break ;
+ default:
+ /* Ignore unknown properties */
+ break ;
+ }
+ }
+ xcfCheckspace(ptr,8,"(end of layer %s)",L->name);
+ L->pixels.tileptrs = 0 ;
+ L->pixels.hierarchy = xcfOffset(ptr ,4*4);
+ L->mask.tileptrs = 0 ;
+ L->mask.hierarchy = xcfOffset(ptr+4,4*4);
+
+ computeDimensions(&L->dim);
+ }
+}
+
diff --git a/kernel/kls_xcf/xcf2pnm/xcf2pnm.c b/kernel/kls_xcf/xcf2pnm/xcf2pnm.c
new file mode 100644
index 0000000..06baf8d
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/xcf2pnm.c
@@ -0,0 +1,269 @@
+/* Convert xcf files to ppm
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xcftools.h"
+#include "flatten.h"
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <ctype.h>
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#include <unistd.h>
+#endif
+#ifndef HAVE_GETOPT_LONG
+#define getopt_long(argc,argv,optstring,l1,l2) getopt(argc,argv,optstring)
+#endif
+
+#include "xcf2pnm.oi"
+
+static int suppress_byline ;
+static struct FlattenSpec flatspec ;
+static FILE *outfile = NULL ;
+static FILE *transfile = NULL ;
+
+static void
+start_writing(FILE **f,int version)
+{
+ const char *format[] = {"(format zero)",
+ "PBM-ascii",
+ "PGM-ascii",
+ "PPM-ascii",
+ "PBM",
+ "PGM",
+ "PPM" };
+
+ if( verboseFlag )
+ fprintf(stderr,f == &outfile ? _("Writing converted image as %s\n")
+ : _("Writing transparency map as %s\n"),
+ format[version]);
+
+ *f = openout( f == &outfile ? flatspec.output_filename
+ : flatspec.transmap_filename );
+ fprintf(*f,"P%d",version);
+ if( suppress_byline )
+ ;
+ else if( f == &outfile )
+ fprintf(*f,_(" # Converted by xcf2pnm %s"),PACKAGE_VERSION);
+ else
+ fprintf(*f,_(" # Transparency map by xcf2pnm %s"),PACKAGE_VERSION);
+ fprintf(*f,"\n%d %d\n%s",
+ flatspec.dim.width,
+ flatspec.dim.height,
+ version == 4 ? "" : "255\n");
+}
+
+int
+put_pbm_row(FILE *file,unsigned num,rgba *pixels,rgba mask);
+
+int
+put_pbm_row(FILE *file,unsigned num,rgba *pixels,rgba mask) {
+ unsigned out ;
+ unsigned i ;
+ int bitsleft = 8 ;
+ out = 0 ;
+ for( i=0; i<num; i++ ) {
+ out <<= 1 ;
+ if( (pixels[i] & mask) == 0 )
+ out++ ; /* 1 is black */
+ else if( (pixels[i] & mask) == mask )
+ ; /* 0 is white */
+ else
+ return 0 ;
+ if( --bitsleft == 0 ) {
+ putc( out, file );
+ out = 0 ;
+ bitsleft = 8 ;
+ }
+ }
+ if( bitsleft < 8 )
+ putc( out << bitsleft, file );
+ return 1 ;
+}
+
+static void
+callback_common(unsigned num,rgba *pixels)
+{
+ if( flatspec.transmap_filename ) {
+ if( flatspec.partial_transparency_mode == ALLOW_PARTIAL_TRANSPARENCY ) {
+ unsigned i ;
+ if( transfile == NULL ) start_writing(&transfile,5);
+ for( i=0; i < num; i++ )
+ putc( ALPHA(pixels[i]), transfile );
+ } else {
+ if( transfile == NULL ) {
+ start_writing(&transfile,4);
+ }
+ /* Partial transparency should have been caught in the flattener,
+ * so just extract a single byte.
+ */
+ put_pbm_row(transfile,num,pixels,(rgba)1 << ALPHA_SHIFT);
+ }
+ } else if( ALPHA(flatspec.default_pixel) < 128 ) {
+ unsigned i ;
+ for( i=0; i < num; i++ )
+ if( !FULLALPHA(pixels[i]) )
+ FatalGeneric(100,_("Transparency found, but -a option not given"));
+ }
+ xcffree(pixels) ;
+}
+
+static void
+ppm_callback(unsigned num,rgba *pixels)
+{
+ unsigned i ;
+ if( outfile == NULL ) start_writing(&outfile,6);
+ for( i=0; i < num; i++ ) {
+ putc( (pixels[i] >> RED_SHIFT) & 0xFF , outfile );
+ putc( (pixels[i] >> GREEN_SHIFT) & 0xFF , outfile );
+ putc( (pixels[i] >> BLUE_SHIFT) & 0xFF , outfile );
+ }
+ callback_common(num,pixels);
+}
+
+static void
+pgm_callback(unsigned num,rgba *pixels)
+{
+ unsigned i ;
+ if( outfile == NULL ) start_writing(&outfile,5);
+ for( i=0; i < num; i++ ) {
+ int gray = degrayPixel(pixels[i]) ;
+ if( gray == -1 )
+ FatalGeneric(103,
+ _("Grayscale output selected, but colored pixel(s) found"));
+ putc( gray, outfile );
+ }
+ callback_common(num,pixels);
+}
+
+static void
+pbm_callback(unsigned num,rgba *pixels)
+{
+ if( outfile == NULL ) start_writing(&outfile,4);
+ if( !put_pbm_row(outfile,num,pixels,
+ ((rgba)255 << RED_SHIFT) +
+ ((rgba)255 << GREEN_SHIFT) +
+ ((rgba)255 << BLUE_SHIFT)) )
+ FatalGeneric(103,_("Monochrome output selected, but not all pixels "
+ "are black or white"));
+ callback_common(num,pixels);
+}
+
+static enum out_color_mode
+guess_color_mode(const char *string)
+{
+ if( strlen(string) >= 3 ) {
+ string += strlen(string)-3 ;
+ if( strcmp(string,"ppm")==0 ) return COLOR_RGB ;
+ if( strcmp(string,"pgm")==0 ) return COLOR_GRAY ;
+ if( strcmp(string,"pbm")==0 ) return COLOR_MONO ;
+ }
+ return COLOR_BY_FILENAME ;
+}
+
+static lineCallback
+selectCallback(void)
+{
+ if( flatspec.transmap_filename && ALPHA(flatspec.default_pixel) >= 128 )
+ FatalGeneric(101,_("The -a option was given, "
+ "but the image has no transparency"));
+
+ switch( flatspec.out_color_mode ) {
+ default:
+ case COLOR_RGB: return &ppm_callback ;
+ case COLOR_GRAY: return &pgm_callback ;
+ case COLOR_MONO: return &pbm_callback ;
+ }
+}
+
+int
+main(int argc,char **argv)
+{
+ int option ;
+ const char *unzipper = NULL ;
+ const char *infile = NULL ;
+
+ setlocale(LC_ALL,"");
+ progname = argv[0] ;
+ nls_init();
+
+ if( argc <= 1 ) gpl_blurb() ;
+
+ init_flatspec(&flatspec) ;
+ flatspec.out_color_mode = COLOR_BY_FILENAME ;
+ while( (option=getopt_long(argc,argv,"-@#"OPTSTRING,longopts,NULL)) >= 0 )
+ switch(option) {
+
+#define OPTION(char,long,desc,man) case char:
+#include "options.i"
+
+ case 1:
+ if( infile )
+ add_layer_request(&flatspec,optarg);
+ else
+ infile = optarg ;
+ break ;
+ case '?':
+ exit(1);
+ case '@':
+ /* Non-documented option for build-time test */
+ suppress_byline = 1 ;
+ break ;
+ case '#':
+ /* Non-documented option for xcfview */
+ flatspec.default_pixel = CHECKERED_BACKGROUND ;
+ break ;
+ default:
+ FatalUnexpected("Getopt(_long) unexpectedly returned '%c'",option);
+ }
+ if( infile == NULL ) {
+ exit(1);
+ }
+
+ if( flatspec.out_color_mode == COLOR_BY_FILENAME &&
+ strlen(flatspec.output_filename) > 4 &&
+ flatspec.output_filename[strlen(flatspec.output_filename)-4] == '.' )
+ flatspec.out_color_mode = guess_color_mode(flatspec.output_filename);
+
+ /* If the output filename was not enough cue, see if we're running
+ * through a symlink/hardlink that gives the required output format
+ */
+ if( flatspec.out_color_mode == COLOR_BY_FILENAME &&
+ strlen(progname) > 3 )
+ flatspec.out_color_mode = guess_color_mode(progname);
+
+ if( flatspec.out_color_mode == COLOR_BY_FILENAME )
+ flatspec.out_color_mode = COLOR_BY_CONTENTS ;
+
+ read_or_mmap_xcf(infile,unzipper);
+ getBasicXcfInfo() ;
+ initColormap();
+
+ complete_flatspec(&flatspec,NULL);
+ if( flatspec.process_in_memory ) {
+ rgba **allPixels = flattenAll(&flatspec);
+ analyse_colormode(&flatspec,allPixels,NULL);
+ shipoutWithCallback(&flatspec,allPixels,selectCallback());
+ } else {
+ flattenIncrementally(&flatspec,selectCallback());
+ }
+ closeout(outfile,flatspec.output_filename) ;
+ closeout(transfile,flatspec.transmap_filename) ;
+ return 0 ;
+}
diff --git a/kernel/kls_xcf/xcf2pnm/xcf2pnm.oi b/kernel/kls_xcf/xcf2pnm/xcf2pnm.oi
new file mode 100644
index 0000000..382bd96
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/xcf2pnm.oi
@@ -0,0 +1,41 @@
+/* Autogenerated by mkopti.pl xcf2pnm */
+#define XCF2PNM
+#define OPTI_TARGET "xcf2pnm"
+#define XCF2FOO
+#define OPTIONGROUP(a,b)
+
+#ifdef HAVE_GETOPT_LONG
+static const struct option longopts[] = {
+ { "help", 0, 0, 'h'},
+ { "version", 0, 0, 'V'},
+ { "verbose", 0, 0, 'v'},
+ { "bzip", 0, 0, 'j'},
+ { "gzip", 0, 0, 'z'},
+ { "unpack", 1, 0, 'Z'},
+ { "output", 1, 0, 'o'},
+ { "alpha", 1, 0, 'a'},
+ { "background", 1, 0, 'b'},
+ { "force-alpha", 0, 0, 'A'},
+ { "color", 0, 0, 'c'},
+ { "colour", 0, 0, 'c'},
+ { "gray", 0, 0, 'g'},
+ { "grey", 0, 0, 'g'},
+ { "mono", 0, 0, 'm'},
+ { "pnm", 0, 0, 'n'},
+ { "truecolor", 0, 0, 'T'},
+ { "for-gif", 0, 0, 'G'},
+ { "dissolve", 0, 0, 'D'},
+ { "full-image", 0, 0, 'f'},
+ { "size", 1, 0, 'S'},
+ { "offset", 1, 0, 'O'},
+ { "autocrop", 0, 0, 'C'},
+ { "mode", 1, 0, 300},
+ { "percent", 1, 0, 301},
+ { "opacity", 1, 0, 302},
+ { "mask", 0, 0, 303},
+ { "nomask", 0, 0, 304},
+ { "utf8", 0, 0, 'u'},
+{0}};
+#endif
+
+#define OPTSTRING "hVvjzZ:o:a:b:AcgmnTGDfS:O:Cu"
diff --git a/kernel/kls_xcf/xcf2pnm/xcftools.h b/kernel/kls_xcf/xcf2pnm/xcftools.h
new file mode 100644
index 0000000..d3efbab
--- /dev/null
+++ b/kernel/kls_xcf/xcf2pnm/xcftools.h
@@ -0,0 +1,182 @@
+/* Generic functions and macros for reading XCF files
+ *
+ * Copyright (C) 2006 Henning Makholm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef XCFTOOLS_H
+#define XCFTOOLS_H
+
+#include "enums.h"
+#include <stddef.h>
+#include <stdio.h>
+
+#define _(s) (s)
+#define nls_init() (void)0
+#define N_(s) (s)
+
+#if HAVE_INTTYPES_H
+# define __STDC_FORMAT_MACROS
+# include <inttypes.h>
+#else
+/* These legacy fall-backs will probably work on every system
+ * that does not supply a inttypes.h ... */
+typedef unsigned char uint8_t ;
+typedef unsigned long int uint32_t, uintptr_t ;
+typedef signed char int8_t ;
+typedef signed long int int32_t ;
+# define PRIX32 "lX"
+# define PRIu32 "lu"
+# define PRIXPTR "lX"
+#endif
+
+#if __GNUC__
+# define __ATTRIBUTE__ __attribute__
+#else
+# define __ATTRIBUTE__(x)
+#endif
+
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#elif HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#elif WORDS_BIGENDIAN
+# define ntohl(x) (x)
+#else
+static inline uint32_t ntohl(uint32_t a) {
+ return (a << 24) + ((a & 0xFF00) << 8) + ((a >> 8) & 0xFF00) + (a >> 24) ;
+}
+#endif
+
+#ifndef HAVE_STRCASECMP
+#define strcasecmp strcmp
+#endif
+
+/* Read a single word value from the XCF file */
+
+/* Use + instead of | because that allows LEA instructions */
+#define xcfBE(a) ( ((uint32_t)xcf_file[(a) ] << 24) + \
+ ((uint32_t)xcf_file[(a)+1] << 16) + \
+ ((uint32_t)xcf_file[(a)+2] << 8 ) + \
+ ((uint32_t)xcf_file[(a)+3] ) )
+#define xcfLE(a) ( ((uint32_t)xcf_file[(a) ] ) + \
+ ((uint32_t)xcf_file[(a)+1] << 8 ) + \
+ ((uint32_t)xcf_file[(a)+2] << 16) + \
+ ((uint32_t)xcf_file[(a)+3] << 24) )
+
+#if CAN_DO_UNALIGNED_WORDS
+# define xcfL(a) ntohl(*(uint32_t *)(xcf_file + (a)))
+#else
+# define xcfL(a) ((a) & 3 ? xcfBE(a) : ntohl(*(uint32_t *)(xcf_file + (a))))
+#endif
+
+/* ****************************************************************** */
+
+/* The following are exported from am OS-specific source file;
+ * io-unix.c on unixish systems.
+ */
+void read_or_mmap_xcf(const char* filename, const char *unzipper);
+void free_or_close_xcf(void);
+
+/* ****************************************************************** */
+/* utils.c */
+
+extern const char *progname ;
+extern int verboseFlag ;
+
+void *xcfmalloc(size_t size);
+void xcffree(void*);
+
+void FatalGeneric(int status,const char* format,...)
+ __ATTRIBUTE__((format(printf,2,3),noreturn)) ;
+void FatalUnexpected(const char* format,...)
+ __ATTRIBUTE__((format(printf,1,2),noreturn)) ;
+void FatalBadXCF(const char* format,...)
+ __ATTRIBUTE__((format(printf,1,2),noreturn)) ;
+void FatalUnsupportedXCF(const char* format,...)
+ __ATTRIBUTE__((format(printf,1,2),noreturn)) ;
+
+void gpl_blurb(void) __ATTRIBUTE__((noreturn));
+
+FILE* openout(const char*);
+void closeout(FILE *,const char*);
+
+struct rect {
+ int t, b, l, r ;
+};
+
+#define isSubrect(A,B) \
+ ((A).l >= (B).l && (A).r <= (B).r && (A).t >= (B).t && (A).b <= (B).b)
+#define disjointRects(A,B) \
+ ((A).l >= (B).r || (A).r <= (B).l || (A).t >= (B).b || (A).b <= (B).t)
+
+/* ****************************************************************** */
+/* xcf-general.c */
+
+extern uint8_t *xcf_file ;
+extern size_t xcf_length ;
+extern int use_utf8 ;
+
+void xcfCheckspace(uint32_t addr,int spaceafter, const char *format,...)
+ __ATTRIBUTE__((format(printf,3,4)));
+uint32_t xcfOffset(uint32_t addr,int spaceafter);
+
+int xcfNextprop(uint32_t *master,uint32_t *body);
+const char* xcfString(uint32_t ptr,uint32_t *after);
+
+/* These are hardcoded in the Gimp sources: */
+#define TILE_WIDTH 64
+#define TILE_HEIGHT 64
+
+struct tileDimensions {
+ struct rect c ;
+ unsigned width, height ;
+ unsigned tilesx, tilesy ;
+ unsigned ntiles ;
+};
+/* computeDimensions assumes that width, height, c.l, and c.t are set */
+void computeDimensions(struct tileDimensions *);
+
+struct xcfTiles {
+ const struct _convertParams *params ;
+ uint32_t *tileptrs ;
+ uint32_t hierarchy ;
+};
+
+struct xcfLayer {
+ struct tileDimensions dim ;
+ const char *name ;
+ GimpLayerModeEffects mode ;
+ GimpImageType type ;
+ unsigned int opacity ;
+ int isVisible, hasMask ;
+ uint32_t propptr ;
+ struct xcfTiles pixels ;
+ struct xcfTiles mask ;
+};
+
+extern struct xcfImage {
+ int version ;
+ unsigned width, height ;
+ GimpImageBaseType type ;
+ XcfCompressionType compression ;
+ int numLayers ;
+ struct xcfLayer *layers ;
+ uint32_t colormapptr ;
+} XCF ;
+
+void getBasicXcfInfo(void);
+
+#endif /* XCFTOOLS_H */
diff --git a/kernel/kls_xcur/Makefile.am b/kernel/kls_xcur/Makefile.am
new file mode 100644
index 0000000..9554260
--- /dev/null
+++ b/kernel/kls_xcur/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_xcur.la
+
+libkls_xcur_la_SOURCES = fmt_codec_xcur.cpp fmt_codec_xcur_defs.h
+
+libkls_xcur_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_xcur_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_xcur/fmt_codec_xcur.cpp b/kernel/kls_xcur/fmt_codec_xcur.cpp
new file mode 100644
index 0000000..28d42f1
--- /dev/null
+++ b/kernel/kls_xcur/fmt_codec_xcur.cpp
@@ -0,0 +1,166 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_xcur_defs.h"
+#include "fmt_codec_xcur.h"
+
+#include "../xpm/codec_xcur.xpm"
+
+/*
+ *
+ * Library to support X cursors.
+ *
+ * You can test it with nice cursors from http://kde-apps.org
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.4.0";
+ o->name = "X Cursors";
+ o->filter = "";
+ o->config = "";
+ o->mime = "Xcur";
+ o->mimetype = "image/x-xcursor";
+ o->pixmap = codec_xcur;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ currentToc = -1;
+
+ if(!frs.readK(&xcur_h, sizeof(XCUR_HEADER))) return SQE_R_BADFILE;
+
+ tocs = new XCUR_CHUNK_DESC [xcur_h.ntoc];
+
+ if(!tocs)
+ return SQE_R_NOMEMORY;
+
+ if(!frs.readK(tocs, sizeof(XCUR_CHUNK_DESC) * xcur_h.ntoc)) return SQE_R_BADFILE;
+
+ lastToc = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(lastToc)
+ {
+ finfo.animated = (currentToc > 0);
+ return SQE_NOTOK;
+ }
+
+ do
+ {
+ currentToc++;
+ }
+ while(tocs[currentToc].type != XCUR_CHUNK_TYPE_IMAGE && currentToc < (s32)xcur_h.ntoc);
+
+ if(currentToc == (s32)xcur_h.ntoc-1)
+ lastToc = true;
+
+ fmt_image image;
+
+ frs.seekg(tocs[currentToc].pos, ios::beg);
+
+ if(!frs.readK(&xcur_chunk, sizeof(XCUR_CHUNK_HEADER))) return SQE_R_BADFILE;
+ if(!frs.readK(&xcur_im, sizeof(XCUR_CHUNK_IMAGE))) return SQE_R_BADFILE;
+
+ image.w = xcur_im.width;
+ image.h = xcur_im.height;
+ image.bpp = 32;
+ image.delay = xcur_im.delay;
+ image.hasalpha = true;
+ image.compression = "-";
+ image.colorspace = "ARGB";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGBA rgba;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ (scan+i)->r = rgba.b;
+ (scan+i)->g = rgba.g;
+ (scan+i)->b = rgba.r;
+ (scan+i)->a = rgba.a;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ delete [] tocs;
+ tocs = NULL;
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_xcur/fmt_codec_xcur_defs.h b/kernel/kls_xcur/fmt_codec_xcur_defs.h
new file mode 100644
index 0000000..301bfab
--- /dev/null
+++ b/kernel/kls_xcur/fmt_codec_xcur_defs.h
@@ -0,0 +1,76 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_xcur
+#define KSQUIRREL_READ_IMAGE_xcur
+
+struct XCUR_CHUNK_DESC
+{
+ u32 type;
+ u32 subtype;
+ u32 pos;
+
+}PACKED;
+
+struct XCUR_HEADER
+{
+ u32 magic;
+ u32 header;
+ u32 version;
+ u32 ntoc;
+
+}PACKED;
+/* Array of XCUR_CHUNK_DESC comes here */
+
+struct XCUR_CHUNK_HEADER
+{
+ u32 header;
+ u32 type;
+ u32 subtype;
+ u32 version;
+
+}PACKED;
+
+struct XCUR_COMMENT_HEADER
+{
+// u32 version;
+ u32 length;
+// s8 *text;
+
+}PACKED;
+
+struct XCUR_CHUNK_IMAGE
+{
+// u32 version;
+// u32 size;
+ u32 width;
+ u32 height;
+ u32 xhot;
+ u32 yhot;
+ u32 delay;
+
+}PACKED;
+
+
+#define XCUR_CHUNK_TYPE_COMMENT 0xFFFE0001
+#define XCUR_CHUNK_TYPE_IMAGE 0xFFFD0002
+
+#endif
diff --git a/kernel/kls_xim/Makefile.am b/kernel/kls_xim/Makefile.am
new file mode 100644
index 0000000..c14de1e
--- /dev/null
+++ b/kernel/kls_xim/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-xim2ppm
+
+pkglib_LTLIBRARIES = libkls_xim.la
+
+libkls_xim_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_xim_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_xim_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_NETPBM -DCODEC_XIM -DNETPBM_S=\"${bindir}/ksquirrel-libs-xim2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-xim2ppm.in
diff --git a/kernel/kls_xim/fmt_codec_pnm.cpp b/kernel/kls_xim/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_xim/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_xim/fmt_codec_pnm_defs.h b/kernel/kls_xim/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_xim/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_xim/ksquirrel-libs-xim2ppm.in b/kernel/kls_xim/ksquirrel-libs-xim2ppm.in
new file mode 100644
index 0000000..a14442f
--- /dev/null
+++ b/kernel/kls_xim/ksquirrel-libs-xim2ppm.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+@XIMTOPPM@ "$1" > "$2" \ No newline at end of file
diff --git a/kernel/kls_xpm/Makefile.am b/kernel/kls_xpm/Makefile.am
new file mode 100644
index 0000000..0188af0
--- /dev/null
+++ b/kernel/kls_xpm/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_xpm.la
+
+libkls_xpm_la_SOURCES = fmt_codec_xpm.cpp fmt_codec_xpm_defs.h xpm_utils.h
+
+libkls_xpm_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_xpm_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DSQ_RGBMAP=\"${pkgdatadir}/rgbmap\"
+
+EXTRA_DIST = rgbmap
+
+install-data-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ $(INSTALL) --mode=0644 rgbmap $(DESTDIR)$(pkgdatadir)/rgbmap \ No newline at end of file
diff --git a/kernel/kls_xpm/fmt_codec_xpm.cpp b/kernel/kls_xpm/fmt_codec_xpm.cpp
new file mode 100644
index 0000000..e3503df
--- /dev/null
+++ b/kernel/kls_xpm/fmt_codec_xpm.cpp
@@ -0,0 +1,258 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <map>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_xpm.h"
+#include "fmt_codec_xpm_defs.h"
+
+#include "xpm_utils.h"
+
+#include "../xpm/codec_xpm.xpm"
+
+/*
+ *
+ * The XPM (X PixMap) format is the current de facto standard for storing X Window
+ * pixmap data to a disk file. This format is supported by many image editors,
+ * graphics window managers, and image file converters.
+ *
+ *
+ * XPM is capable of storing black-and-white, gray-scale, or color image data.
+ * Hotspot information for cursor bitmaps may also be stored. Although small
+ * collections of data, such as icons, are typically associated with XPM files,
+ * there is no limit to the size of an image or the number of colors that may be
+ * stored in an XPM file.
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{
+ fillmap();
+}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.6.4";
+ o->name = "X11 Pixmap";
+ o->filter = "*.xpm ";
+ o->config = "";
+ o->mime = "/\\* XPM \\*/\n";
+ o->mimetype = "image/x-xpm";
+ o->pixmap = codec_xpm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &fl)
+{
+ frs.open(fl.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ file.clear();
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s32 i;
+ s8 str[256];
+
+ s32 ret;
+
+ while(true) { ret = skip_comments(frs); if(ret == 1) continue; else if(!ret) break; else return SQE_R_BADFILE; }
+ if(!frs.getS(str, 256)) return SQE_R_BADFILE;
+ if(strncmp(str, "static", 6) != 0) return SQE_R_BADFILE;
+ while(true) { ret = skip_comments(frs); if(ret == 1) continue; else if(!ret) break; else return SQE_R_BADFILE; }
+ if(!frs.getS(str, 256)) return SQE_R_BADFILE;
+ while(true) { ret = skip_comments(frs); if(ret == 1) continue; else if(!ret) break; else return SQE_R_BADFILE; }
+
+ sscanf(str, "\"%d %d %d %d", &image.w, &image.h, &numcolors, (int*)&cpp);
+
+ if(!numcolors)
+ return SQE_R_BADFILE;
+
+ s8 name[KEY_LENGTH], c[3], color[10], *found;
+
+ for(i = 0;i < numcolors;i++)
+ {
+ if(!frs.getS(str, 256)) return SQE_R_BADFILE;
+
+ if(*str != '\"')
+ {
+ numcolors = i;
+ break;
+ }
+
+ strcpy(name, "");
+
+ found = str;
+ found++;
+
+ strncpy(name, found, cpp);
+ name[cpp] = 0;
+
+ sscanf(found+cpp+1, "%s %s", c, color);
+
+ found = strstr(color, "\"");
+ if(found) *found = 0;
+
+ file[name] = hex2rgb(color);
+ }
+
+ if(!numcolors)
+ return SQE_R_BADFILE;
+
+ while(true) { ret = skip_comments(frs); if(ret == 1) continue; else if(!ret) break; else return SQE_R_BADFILE; }
+
+ image.bpp = 24;
+ image.hasalpha = true;
+ image.passes = 1;
+ image.compression = "-";
+ image.colorspace = "Indexed RGBA";
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ const s32 bpl = im->w * (cpp+2);
+ s32 i, j;
+ s8 line[bpl], key[KEY_LENGTH];
+
+ memset(key, 0, sizeof(key));
+ memset(line, 0, sizeof(line));
+
+ switch(im->bpp)
+ {
+ case 24:
+ {
+ RGBA rgba;
+ bool f;
+
+ i = j = 0;
+ if(!frs.getS(line, sizeof(line))) return SQE_R_BADFILE;
+
+ while(line[i++] != '\"') // skip spaces
+ {}
+
+ for(;j < im->w;j++)
+ {
+ strncpy(key, line+i, cpp);
+ i += cpp;
+
+ std::map<std::string, RGBA>::const_iterator it = file.find(key);
+
+ f = (it != file.end());
+
+ if(!f)
+ {
+ cerr << "XPM decoder: WARNING: color \"" << key << "\" not found, assuming transparent instead" << endl;
+ memset(&rgba, 0, sizeof(RGBA));
+ }
+ else
+ rgba = (*it).second;
+
+ memcpy(scan+j, &rgba, sizeof(RGBA));
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+
+ file.clear();
+}
+
+void fmt_codec::fillmap()
+{
+ s8 name[80];
+ s32 r, g, b, a;
+
+ std::ifstream rgb_fstream;
+
+ rgb_fstream.open(SQ_RGBMAP, ios::in);
+
+ if(!rgb_fstream.good())
+ {
+ std::cerr << "libkls_xpm.so: rgbmap not found" << std::endl;
+ return;
+ }
+
+ typedef std::pair<std::string, RGBA> xpm_pair;
+
+ while(rgb_fstream.good())
+ {
+ rgb_fstream >> name >> r >> g >> b >> a;
+
+ named.insert(xpm_pair(name, RGBA(r,g,b,a)));
+ }
+
+ rgb_fstream.close();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_xpm/fmt_codec_xpm_defs.h b/kernel/kls_xpm/fmt_codec_xpm_defs.h
new file mode 100644
index 0000000..b0a8316
--- /dev/null
+++ b/kernel/kls_xpm/fmt_codec_xpm_defs.h
@@ -0,0 +1,25 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_xpm
+#define KSQUIRREL_READ_IMAGE_xpm
+
+#endif
diff --git a/kernel/kls_xpm/rgbmap b/kernel/kls_xpm/rgbmap
new file mode 100644
index 0000000..399c88e
--- /dev/null
+++ b/kernel/kls_xpm/rgbmap
@@ -0,0 +1,719 @@
+AliceBlue 240 248 255 255
+AntiqueWhite 250 235 215 255
+AntiqueWhite1 255 239 219 255
+AntiqueWhite2 238 223 204 255
+AntiqueWhite3 205 192 176 255
+AntiqueWhite4 139 131 120 255
+BlanchedAlmond 255 235 205 255
+BlueViolet 138 43 226 255
+CadetBlue 95 158 160 255
+CadetBlue1 152 245 255 255
+CadetBlue2 142 229 238 255
+CadetBlue3 122 197 205 255
+CadetBlue4 83 134 139 255
+CornflowerBlue 100 149 237 255
+DarkBlue 0 0 139 255
+DarkCyan 0 139 139 255
+DarkGoldenrod 184 134 11 255
+DarkGoldenrod1 255 185 15 255
+DarkGoldenrod2 238 173 14 255
+DarkGoldenrod3 205 149 12 255
+DarkGoldenrod4 139 101 8 255
+DarkGray 169 169 169 255
+DarkGreen 0 100 0 255
+DarkGrey 169 169 169 255
+DarkKhaki 189 183 107 255
+DarkMagenta 139 0 139 255
+DarkOliveGreen 85 107 47 255
+DarkOliveGreen1 202 255 112 255
+DarkOliveGreen2 188 238 104 255
+DarkOliveGreen3 162 205 90 255
+DarkOliveGreen4 110 139 61 255
+DarkOrange 255 140 0 255
+DarkOrange1 255 127 0 255
+DarkOrange2 238 118 0 255
+DarkOrange3 205 102 0 255
+DarkOrange4 139 69 0 255
+DarkOrchid 153 50 204 255
+DarkOrchid1 191 62 255 255
+DarkOrchid2 178 58 238 255
+DarkOrchid3 154 50 205 255
+DarkOrchid4 104 34 139 255
+DarkRed 139 0 0 255
+DarkSalmon 233 150 122 255
+DarkSeaGreen 143 188 143 255
+DarkSeaGreen1 193 255 193 255
+DarkSeaGreen2 180 238 180 255
+DarkSeaGreen3 155 205 155 255
+DarkSeaGreen4 105 139 105 255
+DarkSlateBlue 72 61 139 255
+DarkSlateGray 47 79 79 255
+DarkSlateGray1 151 255 255 255
+DarkSlateGray2 141 238 238 255
+DarkSlateGray3 121 205 205 255
+DarkSlateGray4 82 139 139 255
+DarkSlateGrey 47 79 79 255
+DarkTurquoise 0 206 209 255
+DarkViolet 148 0 211 255
+DeepPink 255 20 147 255
+DeepPink1 255 20 147 255
+DeepPink2 238 18 137 255
+DeepPink3 205 16 118 255
+DeepPink4 139 10 80 255
+DeepSkyBlue 0 191 255 255
+DeepSkyBlue1 0 191 255 255
+DeepSkyBlue2 0 178 238 255
+DeepSkyBlue3 0 154 205 255
+DeepSkyBlue4 0 104 139 255
+DimGray 105 105 105 255
+DimGrey 105 105 105 255
+DodgerBlue 30 144 255 255
+DodgerBlue1 30 144 255 255
+DodgerBlue2 28 134 238 255
+DodgerBlue3 24 116 205 255
+DodgerBlue4 16 78 139 255
+FloralWhite 255 250 240 255
+ForestGreen 34 139 34 255
+GhostWhite 248 248 255 255
+GreenYellow 173 255 47 255
+HotPink 255 105 180 255
+HotPink1 255 110 180 255
+HotPink2 238 106 167 255
+HotPink3 205 96 144 255
+HotPink4 139 58 98 255
+IndianRed 205 92 92 255
+IndianRed1 255 106 106 255
+IndianRed2 238 99 99 255
+IndianRed3 205 85 85 255
+IndianRed4 139 58 58 255
+LavenderBlush 255 240 245 255
+LavenderBlush1 255 240 245 255
+LavenderBlush2 238 224 229 255
+LavenderBlush3 205 193 197 255
+LavenderBlush4 139 131 134 255
+LawnGreen 124 252 0 255
+LemonChiffon 255 250 205 255
+LemonChiffon1 255 250 205 255
+LemonChiffon2 238 233 191 255
+LemonChiffon3 205 201 165 255
+LemonChiffon4 139 137 112 255
+LightBlue 173 216 230 255
+LightBlue1 191 239 255 255
+LightBlue2 178 223 238 255
+LightBlue3 154 192 205 255
+LightBlue4 104 131 139 255
+LightCoral 240 128 128 255
+LightCyan 224 255 255 255
+LightCyan1 224 255 255 255
+LightCyan2 209 238 238 255
+LightCyan3 180 205 205 255
+LightCyan4 122 139 139 255
+LightGoldenrod 238 221 130 255
+LightGoldenrod1 255 236 139 255
+LightGoldenrod2 238 220 130 255
+LightGoldenrod3 205 190 112 255
+LightGoldenrod4 139 129 76 255
+LightGoldenrodYellow 250 250 210 255
+LightGray 211 211 211 255
+LightGreen 144 238 144 255
+LightGrey 211 211 211 255
+LightPink 255 182 193 255
+LightPink1 255 174 185 255
+LightPink2 238 162 173 255
+LightPink3 205 140 149 255
+LightPink4 139 95 101 255
+LightSalmon 255 160 122 255
+LightSalmon1 255 160 122 255
+LightSalmon2 238 149 114 255
+LightSalmon3 205 129 98 255
+LightSalmon4 139 87 66 255
+LightSeaGreen 32 178 170 255
+LightSkyBlue 135 206 250 255
+LightSkyBlue1 176 226 255 255
+LightSkyBlue2 164 211 238 255
+LightSkyBlue3 141 182 205 255
+LightSkyBlue4 96 123 139 255
+LightSlateBlue 132 112 255 255
+LightSlateGray 119 136 153 255
+LightSlateGrey 119 136 153 255
+LightSteelBlue 176 196 222 255
+LightSteelBlue1 202 225 255 255
+LightSteelBlue2 188 210 238 255
+LightSteelBlue3 162 181 205 255
+LightSteelBlue4 110 123 139 255
+LightYellow 255 255 224 255
+LightYellow1 255 255 224 255
+LightYellow2 238 238 209 255
+LightYellow3 205 205 180 255
+LightYellow4 139 139 122 255
+LimeGreen 50 205 50 255
+MediumAquamarine 102 205 170 255
+MediumBlue 0 0 205 255
+MediumOrchid 186 85 211 255
+MediumOrchid1 224 102 255 255
+MediumOrchid2 209 95 238 255
+MediumOrchid3 180 82 205 255
+MediumOrchid4 122 55 139 255
+MediumPurple 147 112 219 255
+MediumPurple1 171 130 255 255
+MediumPurple2 159 121 238 255
+MediumPurple3 137 104 205 255
+MediumPurple4 93 71 139 255
+MediumSeaGreen 60 179 113 255
+MediumSlateBlue 123 104 238 255
+MediumSpringGreen 0 250 154 255
+MediumTurquoise 72 209 204 255
+MediumVioletRed 199 21 133 255
+MidnightBlue 25 25 112 255
+MintCream 245 255 250 255
+MistyRose 255 228 225 255
+MistyRose1 255 228 225 255
+MistyRose2 238 213 210 255
+MistyRose3 205 183 181 255
+MistyRose4 139 125 123 255
+NavajoWhite 255 222 173 255
+NavajoWhite1 255 222 173 255
+NavajoWhite2 238 207 161 255
+NavajoWhite3 205 179 139 255
+NavajoWhite4 139 121 94 255
+NavyBlue 0 0 128 255
+OldLace 253 245 230 255
+OliveDrab 107 142 35 255
+OliveDrab1 192 255 62 255
+OliveDrab2 179 238 58 255
+OliveDrab3 154 205 50 255
+OliveDrab4 105 139 34 255
+OrangeRed 255 69 0 255
+OrangeRed1 255 69 0 255
+OrangeRed2 238 64 0 255
+OrangeRed3 205 55 0 255
+OrangeRed4 139 37 0 255
+PaleGoldenrod 238 232 170 255
+PaleGreen 152 251 152 255
+PaleGreen1 154 255 154 255
+PaleGreen2 144 238 144 255
+PaleGreen3 124 205 124 255
+PaleGreen4 84 139 84 255
+PaleTurquoise 175 238 238 255
+PaleTurquoise1 187 255 255 255
+PaleTurquoise2 174 238 238 255
+PaleTurquoise3 150 205 205 255
+PaleTurquoise4 102 139 139 255
+PaleVioletRed 219 112 147 255
+PaleVioletRed1 255 130 171 255
+PaleVioletRed2 238 121 159 255
+PaleVioletRed3 205 104 137 255
+PaleVioletRed4 139 71 93 255
+PapayaWhip 255 239 213 255
+PeachPuff 255 218 185 255
+PeachPuff1 255 218 185 255
+PeachPuff2 238 203 173 255
+PeachPuff3 205 175 149 255
+PeachPuff4 139 119 101 255
+PowderBlue 176 224 230 255
+RosyBrown 188 143 143 255
+RosyBrown1 255 193 193 255
+RosyBrown2 238 180 180 255
+RosyBrown3 205 155 155 255
+RosyBrown4 139 105 105 255
+RoyalBlue 65 105 225 255
+RoyalBlue1 72 118 255 255
+RoyalBlue2 67 110 238 255
+RoyalBlue3 58 95 205 255
+RoyalBlue4 39 64 139 255
+SaddleBrown 139 69 19 255
+SandyBrown 244 164 96 255
+SeaGreen 46 139 87 255
+SeaGreen1 84 255 159 255
+SeaGreen2 78 238 148 255
+SeaGreen3 67 205 128 255
+SeaGreen4 46 139 87 255
+SkyBlue 135 206 235 255
+SkyBlue1 135 206 255 255
+SkyBlue2 126 192 238 255
+SkyBlue3 108 166 205 255
+SkyBlue4 74 112 139 255
+SlateBlue 106 90 205 255
+SlateBlue1 131 111 255 255
+SlateBlue2 122 103 238 255
+SlateBlue3 105 89 205 255
+SlateBlue4 71 60 139 255
+SlateGray 112 128 144 255
+SlateGray1 198 226 255 255
+SlateGray2 185 211 238 255
+SlateGray3 159 182 205 255
+SlateGray4 108 123 139 255
+SlateGrey 112 128 144 255
+SpringGreen 0 255 127 255
+SpringGreen1 0 255 127 255
+SpringGreen2 0 238 118 255
+SpringGreen3 0 205 102 255
+SpringGreen4 0 139 69 255
+SteelBlue 70 130 180 255
+SteelBlue1 99 184 255 255
+SteelBlue2 92 172 238 255
+SteelBlue3 79 148 205 255
+SteelBlue4 54 100 139 255
+VioletRed 208 32 144 255
+VioletRed1 255 62 150 255
+VioletRed2 238 58 140 255
+VioletRed3 205 50 120 255
+VioletRed4 139 34 82 255
+WhiteSmoke 245 245 245 255
+YellowGreen 154 205 50 255
+alice 240 248 255 255
+antique 250 235 215 255
+aquamarine 127 255 212 255
+aquamarine1 127 255 212 255
+aquamarine2 118 238 198 255
+aquamarine3 102 205 170 255
+aquamarine4 69 139 116 255
+azure 240 255 255 255
+azure1 240 255 255 255
+azure2 224 238 238 255
+azure3 193 205 205 255
+azure4 131 139 139 255
+beige 245 245 220 255
+bisque 255 228 196 255
+bisque1 255 228 196 255
+bisque2 238 213 183 255
+bisque3 205 183 158 255
+bisque4 139 125 107 255
+black 0 0 0 255
+blanched 255 235 205 255
+blue 138 43 226 255
+blue 0 0 255 255
+blue1 0 0 255 255
+blue2 0 0 238 255
+blue3 0 0 205 255
+blue4 0 0 139 255
+brown 165 42 42 255
+brown1 255 64 64 255
+brown2 238 59 59 255
+brown3 205 51 51 255
+brown4 139 35 35 255
+burlywood 222 184 135 255
+burlywood1 255 211 155 255
+burlywood2 238 197 145 255
+burlywood3 205 170 125 255
+burlywood4 139 115 85 255
+cadet 95 158 160 255
+chartreuse 127 255 0 255
+chartreuse1 127 255 0 255
+chartreuse2 118 238 0 255
+chartreuse3 102 205 0 255
+chartreuse4 69 139 0 255
+chocolate 210 105 30 255
+chocolate1 255 127 36 255
+chocolate2 238 118 33 255
+chocolate3 205 102 29 255
+chocolate4 139 69 19 255
+coral 255 127 80 255
+coral1 255 114 86 255
+coral2 238 106 80 255
+coral3 205 91 69 255
+coral4 139 62 47 255
+cornflower 100 149 237 255
+cornsilk 255 248 220 255
+cornsilk1 255 248 220 255
+cornsilk2 238 232 205 255
+cornsilk3 205 200 177 255
+cornsilk4 139 136 120 255
+cyan 0 255 255 255
+cyan1 0 255 255 255
+cyan2 0 238 238 255
+cyan3 0 205 205 255
+cyan4 0 139 139 255
+dark 72 61 139 255
+dark 0 100 0 255
+deep 255 20 147 255
+deep 0 191 255 255
+dim 105 105 105 255
+dim 105 105 105 255
+dodger 30 144 255 255
+firebrick 178 34 34 255
+firebrick1 255 48 48 255
+firebrick2 238 44 44 255
+firebrick3 205 38 38 255
+firebrick4 139 26 26 255
+floral 255 250 240 255
+forest 34 139 34 255
+gainsboro 220 220 220 255
+ghost 248 248 255 255
+gold 255 215 0 255
+gold1 255 215 0 255
+gold2 238 201 0 255
+gold3 205 173 0 255
+gold4 139 117 0 255
+goldenrod 218 165 32 255
+goldenrod1 255 193 37 255
+goldenrod2 238 180 34 255
+goldenrod3 205 155 29 255
+goldenrod4 139 105 20 255
+gray 190 190 190 255
+gray0 0 0 0 255
+gray1 3 3 3 255
+gray10 26 26 26 255
+gray100 255 255 255 255
+gray11 28 28 28 255
+gray12 31 31 31 255
+gray13 33 33 33 255
+gray14 36 36 36 255
+gray15 38 38 38 255
+gray16 41 41 41 255
+gray17 43 43 43 255
+gray18 46 46 46 255
+gray19 48 48 48 255
+gray2 5 5 5 255
+gray20 51 51 51 255
+gray21 54 54 54 255
+gray22 56 56 56 255
+gray23 59 59 59 255
+gray24 61 61 61 255
+gray25 64 64 64 255
+gray26 66 66 66 255
+gray27 69 69 69 255
+gray28 71 71 71 255
+gray29 74 74 74 255
+gray3 8 8 8 255
+gray30 77 77 77 255
+gray31 79 79 79 255
+gray32 82 82 82 255
+gray33 84 84 84 255
+gray34 87 87 87 255
+gray35 89 89 89 255
+gray36 92 92 92 255
+gray37 94 94 94 255
+gray38 97 97 97 255
+gray39 99 99 99 255
+gray4 10 10 10 255
+gray40 102 102 102 255
+gray41 105 105 105 255
+gray42 107 107 107 255
+gray43 110 110 110 255
+gray44 112 112 112 255
+gray45 115 115 115 255
+gray46 117 117 117 255
+gray47 120 120 120 255
+gray48 122 122 122 255
+gray49 125 125 125 255
+gray5 13 13 13 255
+gray50 127 127 127 255
+gray51 130 130 130 255
+gray52 133 133 133 255
+gray53 135 135 135 255
+gray54 138 138 138 255
+gray55 140 140 140 255
+gray56 143 143 143 255
+gray57 145 145 145 255
+gray58 148 148 148 255
+gray59 150 150 150 255
+gray6 15 15 15 255
+gray60 153 153 153 255
+gray61 156 156 156 255
+gray62 158 158 158 255
+gray63 161 161 161 255
+gray64 163 163 163 255
+gray65 166 166 166 255
+gray66 168 168 168 255
+gray67 171 171 171 255
+gray68 173 173 173 255
+gray69 176 176 176 255
+gray7 18 18 18 255
+gray70 179 179 179 255
+gray71 181 181 181 255
+gray72 184 184 184 255
+gray73 186 186 186 255
+gray74 189 189 189 255
+gray75 191 191 191 255
+gray76 194 194 194 255
+gray77 196 196 196 255
+gray78 199 199 199 255
+gray79 201 201 201 255
+gray8 20 20 20 255
+gray80 204 204 204 255
+gray81 207 207 207 255
+gray82 209 209 209 255
+gray83 212 212 212 255
+gray84 214 214 214 255
+gray85 217 217 217 255
+gray86 219 219 219 255
+gray87 222 222 222 255
+gray88 224 224 224 255
+gray89 227 227 227 255
+gray9 23 23 23 255
+gray90 229 229 229 255
+gray91 232 232 232 255
+gray92 235 235 235 255
+gray93 237 237 237 255
+gray94 240 240 240 255
+gray95 242 242 242 255
+gray96 245 245 245 255
+gray97 247 247 247 255
+gray98 250 250 250 255
+gray99 252 252 252 255
+green 173 255 47 255
+green 0 255 0 255
+green1 0 255 0 255
+green2 0 238 0 255
+green3 0 205 0 255
+green4 0 139 0 255
+grey 190 190 190 255
+grey0 0 0 0 255
+grey1 3 3 3 255
+grey10 26 26 26 255
+grey100 255 255 255 255
+grey11 28 28 28 255
+grey12 31 31 31 255
+grey13 33 33 33 255
+grey14 36 36 36 255
+grey15 38 38 38 255
+grey16 41 41 41 255
+grey17 43 43 43 255
+grey18 46 46 46 255
+grey19 48 48 48 255
+grey2 5 5 5 255
+grey20 51 51 51 255
+grey21 54 54 54 255
+grey22 56 56 56 255
+grey23 59 59 59 255
+grey24 61 61 61 255
+grey25 64 64 64 255
+grey26 66 66 66 255
+grey27 69 69 69 255
+grey28 71 71 71 255
+grey29 74 74 74 255
+grey3 8 8 8 255
+grey30 77 77 77 255
+grey31 79 79 79 255
+grey32 82 82 82 255
+grey33 84 84 84 255
+grey34 87 87 87 255
+grey35 89 89 89 255
+grey36 92 92 92 255
+grey37 94 94 94 255
+grey38 97 97 97 255
+grey39 99 99 99 255
+grey4 10 10 10 255
+grey40 102 102 102 255
+grey41 105 105 105 255
+grey42 107 107 107 255
+grey43 110 110 110 255
+grey44 112 112 112 255
+grey45 115 115 115 255
+grey46 117 117 117 255
+grey47 120 120 120 255
+grey48 122 122 122 255
+grey49 125 125 125 255
+grey5 13 13 13 255
+grey50 127 127 127 255
+grey51 130 130 130 255
+grey52 133 133 133 255
+grey53 135 135 135 255
+grey54 138 138 138 255
+grey55 140 140 140 255
+grey56 143 143 143 255
+grey57 145 145 145 255
+grey58 148 148 148 255
+grey59 150 150 150 255
+grey6 15 15 15 255
+grey60 153 153 153 255
+grey61 156 156 156 255
+grey62 158 158 158 255
+grey63 161 161 161 255
+grey64 163 163 163 255
+grey65 166 166 166 255
+grey66 168 168 168 255
+grey67 171 171 171 255
+grey68 173 173 173 255
+grey69 176 176 176 255
+grey7 18 18 18 255
+grey70 179 179 179 255
+grey71 181 181 181 255
+grey72 184 184 184 255
+grey73 186 186 186 255
+grey74 189 189 189 255
+grey75 191 191 191 255
+grey76 194 194 194 255
+grey77 196 196 196 255
+grey78 199 199 199 255
+grey79 201 201 201 255
+grey8 20 20 20 255
+grey80 204 204 204 255
+grey81 207 207 207 255
+grey82 209 209 209 255
+grey83 212 212 212 255
+grey84 214 214 214 255
+grey85 217 217 217 255
+grey86 219 219 219 255
+grey87 222 222 222 255
+grey88 224 224 224 255
+grey89 227 227 227 255
+grey9 23 23 23 255
+grey90 229 229 229 255
+grey91 232 232 232 255
+grey92 235 235 235 255
+grey93 237 237 237 255
+grey94 240 240 240 255
+grey95 242 242 242 255
+grey96 245 245 245 255
+grey97 247 247 247 255
+grey98 250 250 250 255
+grey99 252 252 252 255
+honeydew 240 255 240 255
+honeydew1 240 255 240 255
+honeydew2 224 238 224 255
+honeydew3 193 205 193 255
+honeydew4 131 139 131 255
+hot 255 105 180 255
+indian 205 92 92 255
+ivory 255 255 240 255
+ivory1 255 255 240 255
+ivory2 238 238 224 255
+ivory3 205 205 193 255
+ivory4 139 139 131 255
+khaki 240 230 140 255
+khaki1 255 246 143 255
+khaki2 238 230 133 255
+khaki3 205 198 115 255
+khaki4 139 134 78 255
+lavender 230 230 250 255
+lavender 255 240 245 255
+lawn 124 252 0 255
+lemon 255 250 205 255
+light 238 221 130 255
+lime 50 205 50 255
+linen 250 240 230 255
+magenta 255 0 255 255
+magenta1 255 0 255 255
+magenta2 238 0 238 255
+magenta3 205 0 205 255
+magenta4 139 0 139 255
+maroon 176 48 96 255
+maroon1 255 52 179 255
+maroon2 238 48 167 255
+maroon3 205 41 144 255
+maroon4 139 28 98 255
+medium 0 0 205 255
+medium 186 85 211 255
+medium 0 250 154 255
+medium 199 21 133 255
+medium 72 209 204 255
+medium 102 205 170 255
+medium 60 179 113 255
+medium 123 104 238 255
+medium 147 112 219 255
+midnight 25 25 112 255
+mint 245 255 250 255
+misty 255 228 225 255
+moccasin 255 228 181 255
+navajo 255 222 173 255
+navy 0 0 128 255
+navy 0 0 128 255
+old 253 245 230 255
+olive 107 142 35 255
+orange 255 69 0 255
+orange 255 165 0 255
+orange1 255 165 0 255
+orange2 238 154 0 255
+orange3 205 133 0 255
+orange4 139 90 0 255
+orchid 218 112 214 255
+orchid1 255 131 250 255
+orchid2 238 122 233 255
+orchid3 205 105 201 255
+orchid4 139 71 137 255
+pale 175 238 238 255
+pale 152 251 152 255
+pale 219 112 147 255
+pale 238 232 170 255
+papaya 255 239 213 255
+peach 255 218 185 255
+peru 205 133 63 255
+pink 255 192 203 255
+pink1 255 181 197 255
+pink2 238 169 184 255
+pink3 205 145 158 255
+pink4 139 99 108 255
+plum 221 160 221 255
+plum1 255 187 255 255
+plum2 238 174 238 255
+plum3 205 150 205 255
+plum4 139 102 139 255
+powder 176 224 230 255
+purple 160 32 240 255
+purple1 155 48 255 255
+purple2 145 44 238 255
+purple3 125 38 205 255
+purple4 85 26 139 255
+red 255 0 0 255
+red1 255 0 0 255
+red2 238 0 0 255
+red3 205 0 0 255
+red4 139 0 0 255
+rosy 188 143 143 255
+royal 65 105 225 255
+saddle 139 69 19 255
+salmon 250 128 114 255
+salmon1 255 140 105 255
+salmon2 238 130 98 255
+salmon3 205 112 84 255
+salmon4 139 76 57 255
+sandy 244 164 96 255
+sea 46 139 87 255
+seashell 255 245 238 255
+seashell1 255 245 238 255
+seashell2 238 229 222 255
+seashell3 205 197 191 255
+seashell4 139 134 130 255
+sienna 160 82 45 255
+sienna1 255 130 71 255
+sienna2 238 121 66 255
+sienna3 205 104 57 255
+sienna4 139 71 38 255
+sky 135 206 235 255
+slate 112 128 144 255
+slate 112 128 144 255
+slate 106 90 205 255
+snow 255 250 250 255
+snow1 255 250 250 255
+snow2 238 233 233 255
+snow3 205 201 201 255
+snow4 139 137 137 255
+spring 0 255 127 255
+steel 70 130 180 255
+tan 210 180 140 255
+tan1 255 165 79 255
+tan2 238 154 73 255
+tan3 205 133 63 255
+tan4 139 90 43 255
+thistle 216 191 216 255
+thistle1 255 225 255 255
+thistle2 238 210 238 255
+thistle3 205 181 205 255
+thistle4 139 123 139 255
+tomato 255 99 71 255
+tomato1 255 99 71 255
+tomato2 238 92 66 255
+tomato3 205 79 57 255
+tomato4 139 54 38 255
+turquoise 64 224 208 255
+turquoise1 0 245 255 255
+turquoise2 0 229 238 255
+turquoise3 0 197 205 255
+turquoise4 0 134 139 255
+violet 208 32 144 255
+violet 238 130 238 255
+wheat 245 222 179 255
+wheat1 255 231 186 255
+wheat2 238 216 174 255
+wheat3 205 186 150 255
+wheat4 139 126 102 255
+white 255 255 255 255
+white 245 245 245 255
+yellow 255 255 0 255
+yellow 154 205 50 255
+yellow1 255 255 0 255
+yellow2 238 238 0 255
+yellow3 205 205 0 255
+yellow4 139 139 0 255 \ No newline at end of file
diff --git a/kernel/kls_xpm/xpm_utils.h b/kernel/kls_xpm/xpm_utils.h
new file mode 100644
index 0000000..d44b2e9
--- /dev/null
+++ b/kernel/kls_xpm/xpm_utils.h
@@ -0,0 +1,103 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <cctype>
+
+#define KEY_LENGTH 25
+
+RGBA fmt_codec::hex2rgb(const s8 *hex)
+{
+ RGBA rgba;
+ s8 c[3];
+ const s8 add = (const s8)strlen(hex+1) / 3 - 2;
+
+ if(!strncasecmp(hex, "none", 4) || !strncasecmp(hex, "one", 3)) // not pretty hack
+ {
+ memset(&rgba, 0, sizeof(RGBA));
+ return rgba;
+ }
+
+ if(isalpha(*hex))
+ {
+ RGBA trgba;
+ bool f;// = BinSearch(named, 0, sizeof(named) / sizeof(XPM_NAMED_COLOR) - 1, hex);
+
+ std::map<std::string, RGBA>::const_iterator it = named.find(hex);
+
+ f = (it != named.end());
+
+ if(!f)
+ {
+ cerr << "XPM decoder: WARNING: named color \"" << hex << "\" not found, assuming transparent instead" << endl;
+ memset(&rgba, 0, sizeof(RGBA));
+ return rgba;
+ }
+
+ trgba = named[std::string(hex)];
+
+ return trgba;
+ }
+
+ hex++;
+
+ memcpy(c, hex, 2);
+ c[2] = 0;
+ rgba.r = (s8)strtol(c, NULL, 16);
+ hex = hex + 2 + add;
+
+ memcpy(c, hex, 2);
+ c[2] = 0;
+ rgba.g = (s8)strtol(c, NULL, 16);
+ hex = hex + 2 + add;
+
+ memcpy(c, hex, 2);
+ c[2] = 0;
+ rgba.b = (s8)strtol(c, NULL, 16);
+
+ rgba.a = 255;
+
+ return rgba;
+}
+
+/* skip a single line C-like comment */
+s32 skip_comments(ifstreamK &ff)
+{
+ s8 str[4096];
+ fstream::pos_type pos;
+ bool skipped = false;
+
+ pos = ff.tellg();
+
+ ff.getline(str, sizeof(str)-1);
+
+ if(ff.eof()) return 2;
+
+ if((*str == '\n' && *(str+1) == '\0') || (*str == '\n' && *(str+1) == '\r' && *(str+2) == '\0') || (*str == '\r' && *(str+1) == '\n' && *(str+2) == '\0'))
+ skipped = true;
+
+ if(strstr(str, "/*") || *str == '#' || !strlen(str))
+ skipped = true;
+
+ if(!skipped)
+ ff.seekg(pos);
+
+ return (int)skipped;
+}
diff --git a/kernel/kls_xwd/Makefile.am b/kernel/kls_xwd/Makefile.am
new file mode 100644
index 0000000..9815d7d
--- /dev/null
+++ b/kernel/kls_xwd/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_xwd.la
+
+libkls_xwd_la_SOURCES = fmt_codec_xwd.cpp fmt_codec_xwd_defs.h
+
+libkls_xwd_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_xwd_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_xwd/fmt_codec_xwd.cpp b/kernel/kls_xwd/fmt_codec_xwd.cpp
new file mode 100644
index 0000000..0ba5226
--- /dev/null
+++ b/kernel/kls_xwd/fmt_codec_xwd.cpp
@@ -0,0 +1,214 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_xwd_defs.h"
+#include "fmt_codec_xwd.h"
+
+#include "../xpm/codec_xwd.xpm"
+
+/*
+ *
+ * The XWD (X Window Dump) format is used specifically to store screen
+ * dumps
+ *
+ * Created by the X Window System. Under X11, screen dumps are created by the
+ * xwd client. Using xwd, the window or background is selected to
+ * dump and an XWD file is produced containing an image of the window. If you
+ * issue the following command:
+ *
+ * $ xwd -root > output.xwd
+ *
+ */
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.4.3";
+ o->name = "X Window Dump";
+ o->filter = "*.xwd ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xwd";
+ o->pixmap = codec_xwd;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ pal = NULL;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ XWDFileHeader xfh;
+
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ XWDColor color;
+ s8 str[256];
+ s32 i, ncolors;
+
+ if(!frs.readK(&xfh, sizeof(XWDFileHeader))) return SQE_R_BADFILE;
+
+ xfh.file_version = fmt_utils::konvertLong(xfh.file_version);
+
+ if(xfh.file_version != XWD_FILE_VERSION)
+ return SQE_R_BADFILE;
+
+ frs.get(str, 255, '\n');
+
+ frs.clear();
+
+ frs.seekg(fmt_utils::konvertLong(xfh.header_size), ios::beg);
+
+ pal_entr = ncolors = fmt_utils::konvertLong(xfh.ncolors);
+
+ pal = new RGB [ncolors];
+
+ if(!pal)
+ return SQE_R_NOMEMORY;
+
+ for(i = 0;i < ncolors;i++)
+ {
+ if(!frs.readK(&color, sizeof(XWDColor))) return SQE_R_BADFILE;
+
+ pal[i].r = (s8)fmt_utils::konvertWord(color.red);
+ pal[i].g = (s8)fmt_utils::konvertWord(color.green);
+ pal[i].b = (s8)fmt_utils::konvertWord(color.blue);
+ }
+
+ image.w = fmt_utils::konvertLong(xfh.pixmap_width);
+ image.h = fmt_utils::konvertLong(xfh.pixmap_height);
+ image.bpp = fmt_utils::konvertLong(xfh.bits_per_pixel);//fmt_utils::konvertLong(xfh.pixmap_depth);
+
+ if(image.bpp != 24 && image.bpp != 32)
+ return SQE_R_NOTSUPPORTED;
+
+ fmt_metaentry mt;
+
+ mt.group = "Window Name";
+ mt.data = str;
+
+ addmeta(mt);
+
+ image.compression = "-";
+ image.colorspace = "RGB";
+
+ filler = fmt_utils::konvertLong(xfh.bytes_per_line) - image.w * image.bpp / 8;
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ s32 i;
+ RGBA rgba;
+ RGB rgb;
+ u8 d;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(im->bpp)
+ {
+ case 24:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgb, sizeof(RGB))) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ for(s32 s = 0;s < filler;s++)
+ if(!frs.readK(&d, 1))
+ return SQE_R_BADFILE;
+ break;
+
+ case 32:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA))) return SQE_R_BADFILE;
+
+ scan[i].r = rgba.b;
+ scan[i].g = rgba.g;
+ scan[i].b = rgba.r;
+ }
+
+ for(s32 s = 0;s < filler;s++)
+ if(!frs.readK(&d, 1))
+ return SQE_R_BADFILE;
+ break;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ delete [] pal;
+ pal = NULL;
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_xwd/fmt_codec_xwd_defs.h b/kernel/kls_xwd/fmt_codec_xwd_defs.h
new file mode 100644
index 0000000..1211f14
--- /dev/null
+++ b/kernel/kls_xwd/fmt_codec_xwd_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_xwd
+#define KSQUIRREL_READ_IMAGE_xwd
+
+#include <X11/XWDFile.h>
+
+#endif
diff --git a/kernel/ksquirrel-libs/Makefile.am b/kernel/ksquirrel-libs/Makefile.am
new file mode 100644
index 0000000..54258cb
--- /dev/null
+++ b/kernel/ksquirrel-libs/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = -I../include
+
+# create small development library. KSquirrel will use it.
+lib_LTLIBRARIES = libksquirrel-libs.la
+
+libksquirrel_libs_la_SOURCES = fileio.cpp fmt_utils.cpp
+
+libksquirrel_libs_la_LDFLAGS = ${SQ_RELEASE} \ No newline at end of file
diff --git a/kernel/ksquirrel-libs/fileio.cpp b/kernel/ksquirrel-libs/fileio.cpp
new file mode 100644
index 0000000..b7cea5c
--- /dev/null
+++ b/kernel/ksquirrel-libs/fileio.cpp
@@ -0,0 +1,136 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fileio.h"
+
+// implement read methods
+ifstreamK::ifstreamK() : ifstream()
+{}
+
+bool ifstreamK::readK(void *data, int size)
+{
+ read((char *)data, size);
+
+ return good();
+}
+
+bool ifstreamK::getS(char *s, const int sz)
+{
+ getline(s, sz);
+
+ return good();
+}
+
+bool ifstreamK::be_getchar(u8 *c)
+{
+ return readK(c, 1);
+}
+
+bool ifstreamK::be_getshort(u16 *s)
+{
+ u8 buf[2];
+
+ if(!readK(buf, 2))
+ return false;
+
+ *s = (buf[0] << 8) + buf[1];
+
+ return good();
+}
+
+bool ifstreamK::be_getlong(u32 *l)
+{
+ u8 buf[4];
+
+ if(!readK(buf, 4))
+ return false;
+
+ *l = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3]);
+
+ return good();
+}
+
+void ifstreamK::close()
+{
+ ifstream::close();
+
+ clear();
+}
+
+bool ifstreamK::readCHex(u32 &hex)
+{
+ s8 prefix1, prefix2;
+ s8 h[9], c;
+ u32 i = 0;
+
+ if(!readK(&prefix1, sizeof(s8)))
+ return false;
+
+ if(!readK(&prefix2, sizeof(s8)))
+ return false;
+
+ if(prefix1 != '0' || prefix2 != 'x')
+ return false;
+
+ while(true)
+ {
+ if(!readK(&c, sizeof(s8)))
+ return false;
+
+ if(c < '0' || c > '9')
+ {
+ if(c != 'A' && c != 'B' && c != 'C' && c != 'D' && c != 'E' && c != 'F')
+ {
+ seekg(-1, ios::cur);
+ break;
+ }
+ }
+
+ h[i++] = c;
+ }
+
+ h[i] = '\0';
+
+ hex = strtol(h, NULL, 16);
+
+ return good();
+}
+
+
+// implement write methods
+ofstreamK::ofstreamK() : ofstream()
+{}
+
+bool ofstreamK::writeK(void *data, int size)
+{
+ write((char *)data, size);
+
+ return good();
+}
+
+void ofstreamK::close()
+{
+ ofstream::close();
+
+ clear();
+}
diff --git a/kernel/ksquirrel-libs/fmt_utils.cpp b/kernel/ksquirrel-libs/fmt_utils.cpp
new file mode 100644
index 0000000..306fee9
--- /dev/null
+++ b/kernel/ksquirrel-libs/fmt_utils.cpp
@@ -0,0 +1,187 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fmt_defs.h"
+
+#include <sstream>
+
+void fmt_utils::fillAlpha(RGBA *scan, int w, u8 value)
+{
+ if(scan)
+ {
+ for(int i = 0;i < w;i++)
+ (scan + i)->a = value;
+ }
+}
+
+void fmt_utils::flipv(s8 *image, s32 bytes_w, s32 h)
+{
+ s32 i;
+
+ if(!image)
+ return;
+
+ s8 *hptr = new s8 [bytes_w];
+
+ if(!hptr)
+ return;
+
+ for(i = 0; i < h/2; i++)
+ {
+ memcpy(hptr, image + i * bytes_w, bytes_w);
+ memcpy(image + i * bytes_w, image + (h - i - 1) * bytes_w, bytes_w);
+ memcpy(image + (h - i - 1) * bytes_w, hptr, bytes_w);
+ }
+
+ delete hptr;
+}
+
+void fmt_utils::fliph(s8 *image, s32 w, s32 h, s32 bpp)
+{
+ s32 x, y, x2;
+ s32 bpl = w * bpp;
+ s8 a[bpp], *t;
+
+ if(!image)
+ return;
+
+ for(y = 0;y < h;y++)
+ {
+ for(x = 0, x2 = w-1;x < w/2;x++,x2--)
+ {
+ t = image + y*bpl;
+
+ memcpy(a, t + x2*bpp, bpp);
+ memcpy(t + x2*bpp, t + x*bpp, bpp);
+ memcpy(t + x*bpp, a, bpp);
+ }
+ }
+}
+
+u16 fmt_utils::konvertWord(u16 a)
+{
+ u16 i = a, b;
+
+ b = i & 255;
+ b = b << 8;
+ b = b|0;
+ i = i >> 8;
+ i = i|0;
+
+ return i|b;
+}
+
+u32 fmt_utils::konvertLong(u32 a)
+{
+ u32 i = a, b, c;
+ u16 m, n;
+
+ b = i >> 16; // high word
+ c = i << 16;
+ c = c >> 16; // low word
+
+ m = (u16)b;
+ n = (u16)c;
+
+ m = fmt_utils::konvertWord(m);
+ n = fmt_utils::konvertWord(n);
+
+ b = m;
+ c = n;
+ c = c << 16;
+
+ b = b|0;
+ c = c|0;
+
+ return b|c;
+}
+
+std::string fmt_utils::colorSpaceByBpp(const int bpp)
+{
+ switch(bpp)
+ {
+ case 1:
+ return std::string("Monochrome");
+
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ return std::string("Color indexed");
+
+ case 24:
+ return std::string("RGB");
+
+ case 32:
+ return std::string("RGBA");
+
+ default:
+ return std::string("Unknown");
+ }
+}
+
+void fmt_utils::expandMono1Byte(const u32 byte, u8 *array)
+{
+ u8 mask = 0x80;
+ u8 *p = array;
+ u8 b = byte & 0xff;
+
+ for(s32 i = 0;i < 8;i++)
+ {
+ *p = (b & mask) ? 1 : 0;
+
+ p++;
+ mask >>= 1;
+ }
+}
+
+void fmt_utils::expandMono2Byte(const u32 byte, u8 *array)
+{
+ u16 mask = 0x8000;
+ u8 *p = array;
+ u16 b = byte & 0xffff;
+
+ for(s32 i = 0;i < 16;i++)
+ {
+ *p = (b & mask) ? 1 : 0;
+
+ p++;
+ mask >>= 1;
+ }
+}
+
+void fmt_utils::expandMono4Byte(const u32 byte, u8 *array)
+{
+ u32 mask = 0x80000000;
+ u8 *p = array;
+ u32 b = byte & 0xffffffff;
+
+ for(s32 i = 0;i < 32;i++)
+ {
+ *p = (b & mask) ? 1 : 0;
+
+ p++;
+ mask >>= 1;
+ }
+}
diff --git a/kernel/link b/kernel/link
new file mode 100755
index 0000000..9256b03
--- /dev/null
+++ b/kernel/link
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# create symlinks from all codecs (bmp/.libs/libkls_bmp.so, ...)
+# to /usr/lib/ksquirrel-libs/
+#
+# Can be used by developers
+#
+# Usage:
+# $ cd ksquirrel-libs/kernel/
+# $ ./link
+#
+
+KSQUIRREL_LIBS="/usr/lib/ksquirrel-libs/"
+
+rm -f $KSQUIRREL_LIBS/*
+
+mkdir $KSQUIRREL_LIBS > /dev/null 2>&1
+
+for i in avs bmp camera cut dds dicom eps fli gif hdr ico iff fig jbig jpeg jpeg2000 koala ljpeg lif mac mdl mng msp mtv openexr pcx pix png pnm psd psp pxr ras rawrgb sct sgi sun svg tga tiff ttf utah wal wbmp wmf xbm xcur xpm xwd djvu dxf xcf neo leaf pi1 pi3 xim pict;
+do echo "Linking libkls_$i.so ..." && ln -s `pwd`/kls_$i/.libs/libkls_$i.so $KSQUIRREL_LIBS;
+done
+
+rm -f /usr/lib/libksquirrel-libs.so
+ln -s `pwd`/ksquirrel-libs/.libs/libksquirrel-libs.so /usr/lib
diff --git a/kernel/plusx b/kernel/plusx
new file mode 100755
index 0000000..4d26ba8
--- /dev/null
+++ b/kernel/plusx
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+for i in /usr/bin/ksquirrel-libs-*; do chmod +x $i; done \ No newline at end of file
diff --git a/kernel/xpm/codec_avs.xpm b/kernel/xpm/codec_avs.xpm
new file mode 100644
index 0000000..c80bd7c
--- /dev/null
+++ b/kernel/xpm/codec_avs.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_avs[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #464646",
+"X c #4E4E4E",
+"o c #CF0008",
+"O c #9EFE02",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX@*****",
+"X########X$+****",
+"X#&&&&&&#X%$@***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"XOOOOOOOOOOOOOO.",
+"XO O OO O O.",
+"XO O O OO O OOO.",
+"XO O OO O O.",
+"XO O O OOO O.",
+"XO O OO OO O.",
+"XOOOOOOOOOOOOOO.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_bmp.xpm b/kernel/xpm/codec_bmp.xpm
new file mode 100644
index 0000000..8048e2b
--- /dev/null
+++ b/kernel/xpm/codec_bmp.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_bmp[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #3F3FBA",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".XXXXXXXXXXXXXX ",
+".X&&&X&XX&X&&&X ",
+".X&X&X&&&&X&X&X ",
+".X&&&X&XX&X&&&X ",
+".X&X&X&XX&X&XXX ",
+".X&&&X&XX&X&XXX ",
+".XXXXXXXXXXXXXX ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_camera.xpm b/kernel/xpm/codec_camera.xpm
new file mode 100644
index 0000000..56f1cc6
--- /dev/null
+++ b/kernel/xpm/codec_camera.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_camera[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #FF00A4",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".o&&&oo&oo&oo&o ",
+".o&o&o&&&o&&&&o ",
+".o&ooo&o&o&oo&o ",
+".o&o&o&&&o&oo&o ",
+".o&&&o&o&o&oo&o ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_cut.xpm b/kernel/xpm/codec_cut.xpm
new file mode 100644
index 0000000..c3f6c28
--- /dev/null
+++ b/kernel/xpm/codec_cut.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_cut[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #842FA3",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".oo&&oo&o&o&&&o ",
+".o&oo&o&o&oo&oo ",
+".o&oooo&o&oo&oo ",
+".o&oo&o&o&oo&oo ",
+".oo&&oo&&&oo&oo ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_dds.xpm b/kernel/xpm/codec_dds.xpm
new file mode 100644
index 0000000..8dcdb37
--- /dev/null
+++ b/kernel/xpm/codec_dds.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_dds[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #F389FA",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=--==--==---==*",
+".=-=-=-=-=-====*",
+".=-=-=-=-=---==*",
+".=-=-=-=-===-==*",
+".=--==--==---==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_dicom.xpm b/kernel/xpm/codec_dicom.xpm
new file mode 100644
index 0000000..48f7106
--- /dev/null
+++ b/kernel/xpm/codec_dicom.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_dicom[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #D8FC0F",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=--==---=-==-=*",
+".=-=-=-===----=*",
+".=-=-=-===-==-=*",
+".=-=-=-===-==-=*",
+".=--==---=-==-=*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_djvu.xpm b/kernel/xpm/codec_djvu.xpm
new file mode 100644
index 0000000..4fcfbae
--- /dev/null
+++ b/kernel/xpm/codec_djvu.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char *codec_djvu[] = {
+"16 16 12 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #35C3E7",
+"- c #FFFFFF",
+"; c #D9F3FA",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=---==---=-=-=*",
+".=-=--===-=-=-=*",
+".=-==-===-=-=-=*",
+".=-=--===-=-=-=*",
+".=---==--;=;-;=*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_dxf.xpm b/kernel/xpm/codec_dxf.xpm
new file mode 100644
index 0000000..86463ee
--- /dev/null
+++ b/kernel/xpm/codec_dxf.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static const char *codec_dxf[] = {
+"16 16 17 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #C69DC1",
+"- c #C69CC1",
+"; c #C69BC1",
+"> c #C69AC1",
+", c #C699C1",
+"' c #C698C1",
+") c #C698C2",
+"! c #FFFFFF",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".=--;;>>,''))))*",
+".)!!!))!)!)!!!)*",
+".)!)!!)!)!)!)))*",
+".)!))!))!))!!!)*",
+".)!)!!)!)!)!)))*",
+".)!!!))!)!)!)))*",
+".))))))))))))))*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_eps.xpm b/kernel/xpm/codec_eps.xpm
new file mode 100644
index 0000000..8715b8c
--- /dev/null
+++ b/kernel/xpm/codec_eps.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char *codec_eps[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #EC23B1",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=---=---=---==*",
+".=-===-=-=-====*",
+".=--==---=---==*",
+".=-===-=====-==*",
+".=---=-===---==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_fig.xpm b/kernel/xpm/codec_fig.xpm
new file mode 100644
index 0000000..0b3777d
--- /dev/null
+++ b/kernel/xpm/codec_fig.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_fig[] = {
+"16 16 11 1",
+" c None",
+". c #4C4C4C",
+"+ c #B0B0B0",
+"@ c #C8C8C8",
+"# c #DDDDDD",
+"$ c #AEAEAE",
+"% c #FFFFFF",
+"& c #F3F3F3",
+"* c #454545",
+"= c #555353",
+"- c #EDFF23",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=-=-=---=----=*",
+".=-=-=-===-====*",
+".==-==---=-=--=*",
+".=-=-=-===-==-=*",
+".=-=-=-===----=*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_fits.xpm b/kernel/xpm/codec_fits.xpm
new file mode 100644
index 0000000..dbbd69f
--- /dev/null
+++ b/kernel/xpm/codec_fits.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_fits[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #D01866",
+"- c #FFFFFF",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=---=---=---==*",
+".=-====-==-====*",
+".=---==-==---==*",
+".=-====-====-==*",
+".=-====-==---==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_fli.xpm b/kernel/xpm/codec_fli.xpm
new file mode 100644
index 0000000..eba7881
--- /dev/null
+++ b/kernel/xpm/codec_fli.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_fli[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #AA0889",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".o&&&&o&ooo&&&o ",
+".o&oooo&oooo&oo ",
+".o&&&oo&oooo&oo ",
+".o&oooo&oooo&oo ",
+".o&oooo&&&o&&&o ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_gif.xpm b/kernel/xpm/codec_gif.xpm
new file mode 100644
index 0000000..f878e33
--- /dev/null
+++ b/kernel/xpm/codec_gif.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_gif[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #008000",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".XXXXXXXXXXXXXX ",
+".XXX&&&X&X&&&XX ",
+".XX&XXXX&X&XXXX ",
+".XX&X&&X&X&&XXX ",
+".XX&XX&X&X&XXXX ",
+".XXX&&&X&X&XXXX ",
+".XXXXXXXXXXXXXX ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_hdr.xpm b/kernel/xpm/codec_hdr.xpm
new file mode 100644
index 0000000..031a577
--- /dev/null
+++ b/kernel/xpm/codec_hdr.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_hdr[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #170100",
+"X c #464646",
+"o c #4E4E4E",
+"O c #AEAEAE",
+"+ c #B2B2B2",
+"@ c #FEE6A2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"oooooooooo+*****",
+"o########o$O****",
+"o#&&&&&&#o%$+***",
+"o#&&&&&&#oooo***",
+"o#&&&&&&####o***",
+"oXXXXXXXXXXXXXXX",
+"o@@@@@@@@@@@@@@X",
+"o@ @ @ @@ @X",
+"o@ @ @ @ @ @ @X",
+"o@ @ @@ @ @X",
+"o@ @ @ @ @ @ @X",
+"o@ @ @ @@ @ @X",
+"o@@@@@@@@@@@@@@X",
+"oXXXXXXXXXXXXXXX",
+"o###########o***",
+"*oooooooooooo***"
+};
diff --git a/kernel/xpm/codec_ico.xpm b/kernel/xpm/codec_ico.xpm
new file mode 100644
index 0000000..4d860eb
--- /dev/null
+++ b/kernel/xpm/codec_ico.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_ico[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #02026E",
+". c #464646",
+"X c #4E4E4E",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c #B2B2B2",
+"@ c #A2FEA2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#XXX.***",
+".#&&&&&&####X***",
+"X...............",
+". .",
+"X @ @@ @@ .",
+"X @ @ @ @ @ .",
+". @ @ @ @ .",
+"X @ @ @ @ @ .",
+"X @ @@ @@ .",
+"X .",
+"X...............",
+"X###########.***",
+"*X.........XX***"
+};
diff --git a/kernel/xpm/codec_iff.xpm b/kernel/xpm/codec_iff.xpm
new file mode 100644
index 0000000..6f6fc74
--- /dev/null
+++ b/kernel/xpm/codec_iff.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_iff[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c red",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".ooo&o&&&o&&&oo ",
+".ooo&o&ooo&oooo ",
+".ooo&o&&oo&&ooo ",
+".ooo&o&ooo&oooo ",
+".ooo&o&ooo&oooo ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_jbig.xpm b/kernel/xpm/codec_jbig.xpm
new file mode 100644
index 0000000..78ebbb7
--- /dev/null
+++ b/kernel/xpm/codec_jbig.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_jbig[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #6D6969",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&&&o&&&o&&&&o.",
+"Xooo&o&o&o&oooo.",
+"Xooo&o&&&o&o&&o.",
+"Xooo&o&o&o&oo&o.",
+"Xo&&&o&&&o&&&&o.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_jpeg.xpm b/kernel/xpm/codec_jpeg.xpm
new file mode 100644
index 0000000..1df6098
--- /dev/null
+++ b/kernel/xpm/codec_jpeg.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_jpeg[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #808000",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".oo&o&&&ooo&&&o ",
+".oo&o&oo&o&oooo ",
+".oo&o&&&oo&o&&o ",
+".&o&o&oooo&oo&o ",
+".&&oo&ooooo&&&o ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_jpeg2000.xpm b/kernel/xpm/codec_jpeg2000.xpm
new file mode 100644
index 0000000..1285008
--- /dev/null
+++ b/kernel/xpm/codec_jpeg2000.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_jpeg2000[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #803F00",
+"o c #CF62EA",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".ooo&o&&&o&&&oo ",
+".ooo&o&o&o&o&oo ",
+".ooo&o&&&ooo&oo ",
+".o&o&o&oooo&ooo ",
+".o&&oo&ooo&&&oo ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_koala.xpm b/kernel/xpm/codec_koala.xpm
new file mode 100644
index 0000000..26f8930
--- /dev/null
+++ b/kernel/xpm/codec_koala.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_koala[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #BC7079",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&oo&o&&&o&&&o.",
+"Xo&&&oo&o&o&o&o.",
+"Xo&&ooo&o&o&o&o.",
+"Xo&&&oo&o&o&&&o.",
+"Xo&oo&o&&&o&o&o.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_lbm.xpm b/kernel/xpm/codec_lbm.xpm
new file mode 100644
index 0000000..4e8145c
--- /dev/null
+++ b/kernel/xpm/codec_lbm.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_lbm[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #DFCE49",
+"- c #1B0D0D",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=-===---=-==-=*",
+".=-===-=-=----=*",
+".=-===---=-==-=*",
+".=-===-=-=-==-=*",
+".=---=---=-==-=*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_leaf.xpm b/kernel/xpm/codec_leaf.xpm
new file mode 100644
index 0000000..bd92645
--- /dev/null
+++ b/kernel/xpm/codec_leaf.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_leaf[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #FFA10D",
+"- c #1B1414",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=-==--=---=--=*",
+".=-==-==-=-=-==*",
+".=-==--=---=--=*",
+".=-==-==-=-=-==*",
+".=--=--=-=-=-==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_lif.xpm b/kernel/xpm/codec_lif.xpm
new file mode 100644
index 0000000..fb0b194
--- /dev/null
+++ b/kernel/xpm/codec_lif.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_lif[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #0AD38D",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo.ooo...o....o.",
+"Xo.oooo.oo.oo.o.",
+"Xo.oooo.oo..ooo.",
+"Xo.oooo.oo.oooo.",
+"Xo...o...o.oooo.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_ljpeg.xpm b/kernel/xpm/codec_ljpeg.xpm
new file mode 100644
index 0000000..dae859d
--- /dev/null
+++ b/kernel/xpm/codec_ljpeg.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char * codec_ljpeg[] = {
+"16 16 10 1",
+" c None",
+". c #4C4C4C",
+"+ c #B0B0B0",
+"@ c #C8C8C8",
+"# c #DDDDDD",
+"$ c #AEAEAE",
+"% c #FFFFFF",
+"& c #F3F3F3",
+"* c #454545",
+"= c #808000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=%=====%=%%%==*",
+".=%=====%=%==%=*",
+".=%=====%=%%%==*",
+".=%===%=%=%====*",
+".=%%%=%%==%====*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_mac.xpm b/kernel/xpm/codec_mac.xpm
new file mode 100644
index 0000000..7b23e88
--- /dev/null
+++ b/kernel/xpm/codec_mac.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_mac[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #0E7175",
+". c gray27",
+"X c #4C4C4C",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"X .",
+"X & & &&& &&& .",
+"X &&&& & & & .",
+"X & & &&& & .",
+"X & & & & & .",
+"X & & & & &&& .",
+"X .",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_mdl.xpm b/kernel/xpm/codec_mdl.xpm
new file mode 100644
index 0000000..f77b4d0
--- /dev/null
+++ b/kernel/xpm/codec_mdl.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_mdl[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #950AD1",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".o&oo&o&&&o&ooo ",
+".o&&&&o&o&o&ooo ",
+".o&oo&o&o&o&ooo ",
+".o&oo&o&o&o&ooo ",
+".o&oo&o&&&o&&&o ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_mng.xpm b/kernel/xpm/codec_mng.xpm
new file mode 100644
index 0000000..6ae4737
--- /dev/null
+++ b/kernel/xpm/codec_mng.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_mng[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #C24E1A",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&oo&o&&oo&&&o.",
+"Xo&&&&o&o&o&ooo.",
+"Xo&oo&o&o&o&o&o.",
+"Xo&oo&o&o&o&o&o.",
+"Xo&oo&o&o&o&&&o.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_msp.xpm b/kernel/xpm/codec_msp.xpm
new file mode 100644
index 0000000..c581155
--- /dev/null
+++ b/kernel/xpm/codec_msp.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_msp[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #000028",
+". c gray27",
+"X c #4C4C4C",
+"o c #E62E8B",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&oo&o&&&o&&&o.",
+"Xo&&&&o&ooo&o&o.",
+"Xo&oo&o&&&o&&&o.",
+"Xo&oo&ooo&o&ooo.",
+"Xo&oo&o&&&o&ooo.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_mtv.xpm b/kernel/xpm/codec_mtv.xpm
new file mode 100644
index 0000000..851a5e3
--- /dev/null
+++ b/kernel/xpm/codec_mtv.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_mtv[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #464646",
+"X c #4E4E4E",
+"o c #CF0008",
+"O c #FEE202",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX@*****",
+"X########X$+****",
+"X#&&&&&&#X%$@***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"XOOOOOOOOOOOOOO.",
+"XO OO O O O O.",
+"XO OO OO O O.",
+"XO OO OO OO O O.",
+"XO OO OO OO O O.",
+"XO OO OO OOO OO.",
+"XOOOOOOOOOOOOOO.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_neo.xpm b/kernel/xpm/codec_neo.xpm
new file mode 100644
index 0000000..df48672
--- /dev/null
+++ b/kernel/xpm/codec_neo.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_neo[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #0DFF2F",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=--==---=---==*",
+".=-=-=-===-=-==*",
+".=-=-=--==-=-==*",
+".=-=-=-===-=-==*",
+".=-=-=---=---==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_openexr.xpm b/kernel/xpm/codec_openexr.xpm
new file mode 100644
index 0000000..72d7ff0
--- /dev/null
+++ b/kernel/xpm/codec_openexr.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_openexr[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #170100",
+"X c #464646",
+"o c #4E4E4E",
+"O c #FEB602",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"oooooooooo@*****",
+"o########o$+****",
+"o#&&&&&&#o%$@***",
+"o#&&&&&&#oooo***",
+"o#&&&&&&####o***",
+"oXXXXXXXXXXXXXXX",
+"oOOOOOOOOOOOOOOX",
+"oO O O O OX",
+" O OOOO O O O OX",
+" O OOO OO OX",
+" O OOOO O O O OX",
+" O O O O O OX",
+"oOOOOOOOOOOOOOOX",
+"oXXXXXXXXXXXXXXX",
+"o###########o***",
+"*oooooooooooo***"
+};
diff --git a/kernel/xpm/codec_pcx.xpm b/kernel/xpm/codec_pcx.xpm
new file mode 100644
index 0000000..298d35b
--- /dev/null
+++ b/kernel/xpm/codec_pcx.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_pcx[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #808080",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".o&&&oo&&&o&o&o ",
+".o&oo&o&o&o&o&o ",
+".o&&&oo&oooo&oo ",
+".o&oooo&o&o&o&o ",
+".o&oooo&&&o&o&o ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_pi1.xpm b/kernel/xpm/codec_pi1.xpm
new file mode 100644
index 0000000..3433ebf
--- /dev/null
+++ b/kernel/xpm/codec_pi1.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_pi1[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #54375E",
+"- c #FFFFFF",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".==---=---==-==*",
+".==-=-==-==--==*",
+".==---==-===-==*",
+".==-====-===-==*",
+".==-===---==-==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_pi3.xpm b/kernel/xpm/codec_pi3.xpm
new file mode 100644
index 0000000..f9ff285
--- /dev/null
+++ b/kernel/xpm/codec_pi3.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_pi3[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #54375E",
+"- c #FFFFFF",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".==---=---=---=*",
+".==-=-==-====-=*",
+".==---==-===--=*",
+".==-====-====-=*",
+".==-===---=---=*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_pict.xpm b/kernel/xpm/codec_pict.xpm
new file mode 100644
index 0000000..c5c3517
--- /dev/null
+++ b/kernel/xpm/codec_pict.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_pict[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #33C8FF",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=---=-=--=---=*",
+".=-=-=-=-===-==*",
+".=---=-=-===-==*",
+".=-===-=-===-==*",
+".=-===-=--==-==*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_pix.xpm b/kernel/xpm/codec_pix.xpm
new file mode 100644
index 0000000..575286f
--- /dev/null
+++ b/kernel/xpm/codec_pix.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_pix[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #464646",
+"X c #4E4E4E",
+"o c #CF0008",
+"O c #FECE32",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX@*****",
+"X########X$+****",
+"X#&&&&&&#.%$@***",
+".#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"................",
+"XOOOOOOOOOOOOOO.",
+".OO OO O O OO.",
+"XOO OO O O O OO.",
+".OO OO OO OOO.",
+"XOO OOOO O O OO.",
+".OO OOOO O O OO.",
+"XOOOOOOOOOOOOOO.",
+"................",
+"X###@#######.***",
+"*..XX......XX***"
+};
diff --git a/kernel/xpm/codec_png.xpm b/kernel/xpm/codec_png.xpm
new file mode 100644
index 0000000..2947900
--- /dev/null
+++ b/kernel/xpm/codec_png.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_png[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #800000",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".XXXXXXXXXXXXXX ",
+".&&&XX&XX&XX&&& ",
+".&XX&X&&X&X&XXX ",
+".&&&XX&X&&X&X&& ",
+".&XXXX&XX&X&XX& ",
+".&XXXX&XX&XX&&& ",
+".XXXXXXXXXXXXXX ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_pnm.xpm b/kernel/xpm/codec_pnm.xpm
new file mode 100644
index 0000000..42413d3
--- /dev/null
+++ b/kernel/xpm/codec_pnm.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_pnm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #FF5050",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".&&&oo&oo&o&oo& ",
+".&oo&o&&o&o&&&& ",
+".&&&oo&o&&o&oo& ",
+".&oooo&oo&o&oo& ",
+".&oooo&oo&o&oo& ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_psd.xpm b/kernel/xpm/codec_psd.xpm
new file mode 100644
index 0000000..1729db8
--- /dev/null
+++ b/kernel/xpm/codec_psd.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_psd[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #464646",
+". c #4E4E4E",
+"X c #5A5A5A",
+"o c #CF0008",
+"O c #FEFE02",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"..........@*****",
+" ######## $+****",
+" #&&&&&&# %$@***",
+" #&&&&&&#... ***",
+" #&&&&&&####.***",
+". ",
+" OOOOOOOOOOOOOO ",
+".XXXOOOXXXOXXXO ",
+" XOOXOXOOOOXOOX ",
+".XXXOOOXXOOXOOX ",
+".XOOOOOOOXOXOOX ",
+" XOOOOXXXOOXXXO ",
+".OOOOOOOOOOOOOO ",
+" ",
+".########### ***",
+"*. . . . .***"
+};
diff --git a/kernel/xpm/codec_psp.xpm b/kernel/xpm/codec_psp.xpm
new file mode 100644
index 0000000..8fe9419
--- /dev/null
+++ b/kernel/xpm/codec_psp.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_psp[] = {
+"16 16 11 1",
+" c None",
+". c #4C4C4C",
+"+ c #B0B0B0",
+"@ c #C8C8C8",
+"# c #DDDDDD",
+"$ c #AEAEAE",
+"% c #FFFFFF",
+"& c #F3F3F3",
+"* c #454545",
+"= c #4CC4F0",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=---=---=---==*",
+".=-=-=-===-=-==*",
+".=---=---=---==*",
+".=-=====-=-====*",
+".=-===---=-====*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_pxr.xpm b/kernel/xpm/codec_pxr.xpm
new file mode 100644
index 0000000..d61249f
--- /dev/null
+++ b/kernel/xpm/codec_pxr.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_pxr[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #7D1AC2",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&&&o&o&o&&&oo.",
+"Xo&o&o&o&o&o&oo.",
+"Xo&&&oo&oo&&&oo.",
+"Xo&ooo&o&o&o&oo.",
+"Xo&ooo&o&o&o&oo.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_ras.xpm b/kernel/xpm/codec_ras.xpm
new file mode 100644
index 0000000..15d5627
--- /dev/null
+++ b/kernel/xpm/codec_ras.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_ras[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #464646",
+"X c #4E4E4E",
+"o c #66FECE",
+"O c #CF0008",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX@*****",
+"X########X$+****",
+"X#&&&&&&#.%$@***",
+".#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"................",
+"Xoooooooooooooo.",
+"X ooo ooo .",
+"X oo oo oo ooo.",
+"X oo oo oo o.",
+"X oo o oooo .",
+"X oo o oo o o.",
+"Xoooooooooooooo.",
+"................",
+"X###########.***",
+"*..........XX***"
+};
diff --git a/kernel/xpm/codec_rawrgb.xpm b/kernel/xpm/codec_rawrgb.xpm
new file mode 100644
index 0000000..f96bf2d
--- /dev/null
+++ b/kernel/xpm/codec_rawrgb.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_rawrgb[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #464646",
+". c #4E4E4E",
+"X c #566A8E",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c gray87",
+"$ c #EEEEFE",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"..........+*****",
+" @@@@@@@@ #O****",
+" @&&&&&&@ %#+***",
+" @&&&&&&@... ***",
+" @&&&&&&@@@@.***",
+". ",
+" XXXXXXXXXXXXXX ",
+".$$$XX$$$X$XXX$ ",
+" $XX$X#X$X$X$X$ ",
+".$#$XX$X$X#X$X$ ",
+".$XX$X$$$XX$X#X ",
+" $XX$X$X$XX$X$X ",
+".XXXXXXXXXXXXXX ",
+" ",
+".@@@@@@@@@@@ ***",
+"* ..***"
+};
diff --git a/kernel/xpm/codec_sct.xpm b/kernel/xpm/codec_sct.xpm
new file mode 100644
index 0000000..370bbce
--- /dev/null
+++ b/kernel/xpm/codec_sct.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_sct[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #E05787",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".oo&&&o&&&o&&&o ",
+".o&oooo&oooo&oo ",
+".oo&&oo&oooo&oo ",
+".oooo&o&oooo&oo ",
+".o&&&oo&&&oo&oo ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_sgi.xpm b/kernel/xpm/codec_sgi.xpm
new file mode 100644
index 0000000..0bcbaf9
--- /dev/null
+++ b/kernel/xpm/codec_sgi.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_sgi[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c magenta",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".oo&&&oo&&&o&&o ",
+".o&oooo&ooooo&o ",
+".oo&&oo&o&&oo&o ",
+".oooo&o&oo&oo&o ",
+".o&&&ooo&&&o&&o ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_sun.xpm b/kernel/xpm/codec_sun.xpm
new file mode 100644
index 0000000..9f97753
--- /dev/null
+++ b/kernel/xpm/codec_sun.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_sun[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #464646",
+". c #4E4E4E",
+"X c #727272",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c #B2B2B2",
+"@ c #96FEAA",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"..........+*****",
+" ######## $O****",
+" #&&&&&&# %$+***",
+" #&&&&&&#... ***",
+" #&&&&&&####.***",
+". ",
+" XXXXXXXXXXXXXX ",
+" X@@@X@XX@X@XX@ ",
+" @XXXX@XX@X@@X@ ",
+" X@@XX@XX@X@X@@ ",
+" XXX@X@XX@X@XX@ ",
+" @@@XXX@@XX@XX@ ",
+" XXXXXXXXXXXXXX ",
+" ",
+" ##+#+#+##+# ***",
+"* . .. . ***"
+};
diff --git a/kernel/xpm/codec_svg.xpm b/kernel/xpm/codec_svg.xpm
new file mode 100644
index 0000000..570b577
--- /dev/null
+++ b/kernel/xpm/codec_svg.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_svg[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #000028",
+". c gray27",
+"X c #4C4C4C",
+"o c #D86800",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&&&o&o&o&&&oo.",
+"Xo&ooo&o&o&oooo.",
+"Xo&&&o&o&o&o&&o.",
+"Xooo&o&&&o&oo&o.",
+"Xo&&&oo&oo&&&&o.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_tga.xpm b/kernel/xpm/codec_tga.xpm
new file mode 100644
index 0000000..3368d8d
--- /dev/null
+++ b/kernel/xpm/codec_tga.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_tga[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #008080",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".XXXXXXXXXXXXXX ",
+".X&&&XX&&&X&&&X ",
+".XX&XX&XXXX&X&X ",
+".XX&XX&X&&X&X&X ",
+".XX&XX&XX&X&&&X ",
+".XX&XXX&&&X&X&X ",
+".XXXXXXXXXXXXXX ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_tiff.xpm b/kernel/xpm/codec_tiff.xpm
new file mode 100644
index 0000000..594fdc6
--- /dev/null
+++ b/kernel/xpm/codec_tiff.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_tiff[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #000099",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".XXXXXXXXXXXXXX ",
+".X&&&X&X&&X&&&X ",
+".XX&XX&X&XX&XXX ",
+".XX&XX&X&&X&&XX ",
+".XX&XX&X&XX&XXX ",
+".XX&XX&X&XX&XXX ",
+".XXXXXXXXXXXXXX ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_ttf.xpm b/kernel/xpm/codec_ttf.xpm
new file mode 100644
index 0000000..faeb818
--- /dev/null
+++ b/kernel/xpm/codec_ttf.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_ttf[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #E94A8D",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"Xo&&&o&&&o&&&&o.",
+"Xoo&ooo&oo&oooo.",
+"Xoo&ooo&oo&&&oo.",
+"Xoo&ooo&oo&oooo.",
+"Xoo&ooo&oo&oooo.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_utah.xpm b/kernel/xpm/codec_utah.xpm
new file mode 100644
index 0000000..8335d0e
--- /dev/null
+++ b/kernel/xpm/codec_utah.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_utah[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #464646",
+"X c #4E4E4E",
+"o c #CF0008",
+"O c #AAC25A",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX@*****",
+"X########X$+****",
+"X#&&&&&&#.%$@***",
+".#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"................",
+"XOOOOOOOOOOOOOO.",
+".O OO OOO O.",
+"XO OO O OOO OOO.",
+"XO OO OOO OO.",
+"XO OO O OOO OOO.",
+"XO OO O O O.",
+"XOOOOOOOOOOOOOO.",
+"................",
+"X###########.***",
+"*..........XX***"
+};
diff --git a/kernel/xpm/codec_wal.xpm b/kernel/xpm/codec_wal.xpm
new file mode 100644
index 0000000..a7bd66b
--- /dev/null
+++ b/kernel/xpm/codec_wal.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_wal[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #C6498E",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".&ooo&oo&&oo&oo ",
+".&o&o&o&oo&o&oo ",
+".&o&o&o&oo&o&oo ",
+".o&o&oo&&&&o&oo ",
+".o&o&oo&oo&o&&& ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_wbmp.xpm b/kernel/xpm/codec_wbmp.xpm
new file mode 100644
index 0000000..6b281a2
--- /dev/null
+++ b/kernel/xpm/codec_wbmp.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_wbmp[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c gray27",
+". c #4C4C4C",
+"X c #CF0008",
+"o c #B9A700",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"..........+*****",
+".########.$O****",
+".#&&&&&&#.%$+***",
+".#&&&&&&#....***",
+".#&&&&&&####.***",
+". ",
+".oooooooooooooo ",
+".&ooo&o&&&o&oo& ",
+".&o&o&o&o&o&&&& ",
+".&o&o&o&&&o&oo& ",
+".o&o&oo&o&o&oo& ",
+".o&o&oo&&&o&oo& ",
+".oooooooooooooo ",
+". ",
+".###########.***",
+"*............***"
+};
diff --git a/kernel/xpm/codec_wmf.xpm b/kernel/xpm/codec_wmf.xpm
new file mode 100644
index 0000000..95cd878
--- /dev/null
+++ b/kernel/xpm/codec_wmf.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_wmf[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c black",
+". c gray27",
+"X c #4C4C4C",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"X .",
+"X& & & & &&&.",
+"X& & & &&&& & .",
+"X& & & & & && .",
+"X & & & & & .",
+"X & & & & & .",
+"X .",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_xbm.xpm b/kernel/xpm/codec_xbm.xpm
new file mode 100644
index 0000000..d5a9f51
--- /dev/null
+++ b/kernel/xpm/codec_xbm.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_xbm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #464646",
+". c #4E4E4E",
+"X c #0202CA",
+"o c #CF0008",
+"O c #AEAEAE",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c gray87",
+"$ c #FEFECA",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"..........+*****",
+" @@@@@@@@ #O****",
+" @&&&&&&@ %#+***",
+" @&&&&&&@... ***",
+" @&&&&&&@@@@.***",
+". ",
+" XXXXXXXXXXXXXX ",
+".$X$X$$$XX$XXX$ ",
+" $X$X$XX$X$$X$$ ",
+".X$XX$$$XX$X$X$ ",
+" $X$X$XX$X$XXX$ ",
+".$X$X$$$XX$XXX$ ",
+".XXXXXXXXXXXXXX ",
+" ",
+" @@@@@@@@@@@ ***",
+"* .***"
+};
diff --git a/kernel/xpm/codec_xcf.xpm b/kernel/xpm/codec_xcf.xpm
new file mode 100644
index 0000000..d8288f4
--- /dev/null
+++ b/kernel/xpm/codec_xcf.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char *codec_xcf[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #FFB3E0",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=-=-=---=---==*",
+".=-=-=-===-====*",
+".==-==-===---==*",
+".=-=-=-===-====*",
+".=-=-=---=-====*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_xcur.xpm b/kernel/xpm/codec_xcur.xpm
new file mode 100644
index 0000000..dda239e
--- /dev/null
+++ b/kernel/xpm/codec_xcur.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_xcur[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #020202",
+". c #464646",
+"X c #4E4E4E",
+"o c #CF0008",
+"O c #FEFE02",
+"+ c #AEAEAE",
+"@ c #B2B2B2",
+"# c #CACACA",
+"$ c gray87",
+"% c gray95",
+"& c #FEFEFE",
+"* c None",
+/* pixels */
+"XXXXXXXXXX@*****",
+"X########X$+****",
+"X#&&&&&&#.%$@***",
+".#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"................",
+"XOOOOOOOOOOOOOO.",
+"X O OOOOOOOOOOO.",
+"X O OOOOOOOOOOO.",
+"XO OOO O O O .",
+"X O O OOO O O O.",
+"X O OO OO O O.",
+"XOOOOOOOOOOOOOO.",
+"X...............",
+"X###########.***",
+"*X.........XX***"
+};
diff --git a/kernel/xpm/codec_xim.xpm b/kernel/xpm/codec_xim.xpm
new file mode 100644
index 0000000..85eafa2
--- /dev/null
+++ b/kernel/xpm/codec_xim.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * codec_xim[] = {
+"16 16 11 1",
+" c None",
+". c #4E4E4E",
+"+ c #B2B2B2",
+"@ c #CACACA",
+"# c #DEDEDE",
+"$ c #AEAEAE",
+"% c #FEFEFE",
+"& c #F2F2F2",
+"* c #464646",
+"= c #FDFCB7",
+"- c #000000",
+"..........+ ",
+".@@@@@@@@.#$ ",
+".@%%%%%%@.&#+ ",
+".@%%%%%%@.... ",
+".@%%%%%%@@@@. ",
+".***************",
+".==============*",
+".=-=-=---=-==-=*",
+".=-=-==-==----=*",
+".==-===-==-==-=*",
+".=-=-==-==-==-=*",
+".=-=-=---=-==-=*",
+".==============*",
+".***************",
+".@@@@@@@@@@@. ",
+" ............ "};
diff --git a/kernel/xpm/codec_xpm.xpm b/kernel/xpm/codec_xpm.xpm
new file mode 100644
index 0000000..098cb40
--- /dev/null
+++ b/kernel/xpm/codec_xpm.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #000002",
+". c gray27",
+"X c #4C4C4C",
+"o c #5F5F5F",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"X&o&o&&&oo&ooo&.",
+"X&o&o&oo&o&&o&&.",
+"Xo&oo&&&oo&o&o&.",
+"X&o&o&oooo&ooo&.",
+"X&o&o&oooo&ooo&.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/kernel/xpm/codec_xwd.xpm b/kernel/xpm/codec_xwd.xpm
new file mode 100644
index 0000000..703e623
--- /dev/null
+++ b/kernel/xpm/codec_xwd.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *codec_xwd[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 12 1",
+" c #000028",
+". c gray27",
+"X c #4C4C4C",
+"o c #890C53",
+"O c #AEAEAE",
+"+ c gray69",
+"@ c #B1B1B1",
+"# c #C8C8C8",
+"$ c #DDDDDD",
+"% c #F3F3F3",
+"& c gray100",
+"* c None",
+/* pixels */
+"XXXXXXXXXX+*****",
+"X########X$O****",
+"X#&&&&&&#X%$+***",
+"X#&&&&&&#XXXX***",
+"X#&&&&&&####X***",
+"X...............",
+"Xoooooooooooooo.",
+"X&o&o&ooo&o&&&o.",
+"X&o&o&o&o&o&oo&.",
+"Xo&oo&o&o&o&oo&.",
+"X&o&oo&o&oo&oo&.",
+"X&o&oo&o&oo&&&o.",
+"Xoooooooooooooo.",
+"X...............",
+"X###########X***",
+"*XXXXXXXXXXXX***"
+};
diff --git a/ksquirrellibs.pc.in b/ksquirrellibs.pc.in
new file mode 100644
index 0000000..83d2e1b
--- /dev/null
+++ b/ksquirrellibs.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+version=@VERSION@
+
+Name: ksquirrellibs
+Description: Image codecs for KSquirrel
+Version: @VERSION@
+Libs: -L${libdir} -lksquirrel-libs
+Cflags: -I${includedir} -DSQ_KLIBS=\"\\\"${libdir}/ksquirrel-libs\\\"\" -DSQ_KL_VER=\"\\\"${version}\\\"\" \ No newline at end of file
diff --git a/patch-stamp b/patch-stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/patch-stamp
diff --git a/reconfigure b/reconfigure
new file mode 100755
index 0000000..be68071
--- /dev/null
+++ b/reconfigure
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+make -f Makefile.dist && ./configure.gnu
diff --git a/required-etch b/required-etch
new file mode 100755
index 0000000..86b3b47
--- /dev/null
+++ b/required-etch
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+#
+# Install required packages in Debian Etch
+#
+# Run this as root before ./configure.gnu
+#
+
+aptitude install libjpeg62 libjpeg62-dev libopenexr2c2a libopenexr-dev \
+ libmng1 libmng-dev libpng12-0 libpng12-dev transfig \
+ netpbm djvulibre-bin libfreetype6 libfreetype6-dev \
+ libjasper-1.701-1 libjasper-1.701-dev libtiff4 \
+ libtiff4-dev libungif4g libungif4-dev libwmf0.2-7 \
+ libwmf-dev librsvg2-bin \ No newline at end of file
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/stamp-h.in
diff --git a/subdirs b/subdirs
new file mode 100644
index 0000000..9639753
--- /dev/null
+++ b/subdirs
@@ -0,0 +1,2 @@
+doc
+kernel