The following builds for me: basebmp, basegfx, comphelper, dtrans, i18npool, i18nutil, l10ntools, o3tl, psprint_config, regexp, rsc, sax, sot, tools, ucbhelper, unotools, vcl The rest still needs fixing ;-) Conflicts: canvas/prj/build.lst canvas/source/cairo/cairo_textlayout.cxx canvas/source/directx/dx_winstuff.hxx canvas/source/tools/image.cxx canvas/source/vcl/canvashelper.cxx comphelper/inc/comphelper/documentconstants.hxx comphelper/inc/comphelper/optionalvalue.hxx comphelper/inc/comphelper/querydeep.hxx comphelper/prj/build.lst comphelper/qa/complex/makefile.mk comphelper/qa/string/test_string_noadditional.cxx comphelper/source/misc/componentmodule.cxx comphelper/source/misc/mimeconfighelper.cxx comphelper/source/misc/querydeep.cxx comphelper/source/misc/uieventslogger.cxx comphelper/source/property/TypeGeneration.cxx comphelper/test/uno_iterators/uno_iterators.cxx comphelper/util/makefile.mk cppcanvas/source/mtfrenderer/implrenderer.cxx dtrans/prj/build.lst dtrans/source/generic/dtrans.cxx dtrans/source/win32/dtobj/FmtFilter.cxx i18npool/prj/build.lst i18npool/source/localedata/data/localedata_others.map i18npool/source/localedata/data/makefile.mk i18npool/source/localedata/localedata.cxx i18npool/source/localedata/saxparser.cxx i18npool/source/registerservices/registerservices.cxx i18npool/source/search/textsearch.cxx l10ntools/inc/cfgmerge.hxx l10ntools/inc/export.hxx l10ntools/inc/gsicheck.hxx l10ntools/inc/l10ntools/vosapp.hxx l10ntools/inc/tagtest.hxx l10ntools/inc/xmlparse.hxx l10ntools/layout/layoutparse.cxx l10ntools/layout/tralay.cxx l10ntools/source/cfgmerge.cxx l10ntools/source/export.cxx l10ntools/source/export2.cxx l10ntools/source/gsicheck.cxx l10ntools/source/help/HelpLinker.cxx l10ntools/source/lngex.cxx l10ntools/source/lngmerge.cxx l10ntools/source/merge.cxx l10ntools/source/tagtest.cxx l10ntools/source/xmlparse.cxx padmin/source/fontentry.cxx padmin/source/padialog.cxx padmin/source/padialog.src padmin/source/pamain.cxx rsc/inc/rscarray.hxx rsc/inc/rscclass.hxx rsc/inc/rscclobj.hxx rsc/inc/rsccont.hxx rsc/inc/rscdb.hxx rsc/inc/rscdef.hxx rsc/inc/rscmgr.hxx rsc/inc/rscrange.hxx rsc/inc/rsctop.hxx rsc/inc/vclrsc.hxx rsc/source/parser/rscdb.cxx rsc/source/parser/rscicpx.cxx rsc/source/parser/rscinit.cxx rsc/source/prj/start.cxx rsc/source/res/rscarray.cxx rsc/source/res/rscclass.cxx rsc/source/res/rscclobj.cxx rsc/source/res/rsccont.cxx rsc/source/res/rscmgr.cxx rsc/source/res/rscrange.cxx rsc/source/res/rsctop.cxx rsc/source/rsc/rsc.cxx rsc/source/tools/rscdef.cxx rsc/source/tools/rsctools.cxx sax/source/expatwrap/sax_expat.cxx sax/source/fastparser/facreg.cxx sax/source/tools/fastserializer.cxx sot/inc/sot/filelist.hxx sot/inc/sot/object.hxx sot/source/base/factory.cxx sot/source/base/filelist.cxx sot/source/sdstor/stg.cxx sot/source/sdstor/stgcache.cxx sot/source/sdstor/stgole.cxx sot/source/sdstor/stgstrms.cxx sot/source/sdstor/storage.cxx sot/source/sdstor/ucbstorage.cxx svl/inc/svl/cenumitm.hxx svl/inc/svl/cintitem.hxx svl/inc/svl/cntwall.hxx svl/inc/svl/ctypeitm.hxx svl/inc/svl/custritm.hxx svl/inc/svl/dateitem.hxx svl/inc/svl/filerec.hxx svl/inc/svl/globalnameitem.hxx svl/inc/svl/ilstitem.hxx svl/inc/svl/imageitm.hxx svl/inc/svl/intitem.hxx svl/inc/svl/itempool.hxx svl/inc/svl/itemset.hxx svl/inc/svl/lckbitem.hxx svl/inc/svl/poolitem.hxx svl/inc/svl/ptitem.hxx svl/inc/svl/rectitem.hxx svl/inc/svl/sfontitm.hxx svl/inc/svl/slstitm.hxx svl/inc/svl/srchitem.hxx svl/inc/svl/svarray.hxx svl/inc/svl/svdde.hxx svl/inc/svl/svstdarr.hxx svl/inc/svl/szitem.hxx svl/inc/svl/visitem.hxx svl/inc/svl/zforlist.hxx svl/inc/svl/zformat.hxx svl/prj/build.lst svl/qa/complex/ConfigItems/helper/ConfigItemTest.cxx svl/qa/complex/ConfigItems/helper/makefile.mk svl/qa/makefile.mk svl/source/filepicker/pickerhelper.cxx svl/source/filerec/filerec.cxx svl/source/items/cenumitm.cxx svl/source/items/cintitem.cxx svl/source/items/cntwall.cxx svl/source/items/ctypeitm.cxx svl/source/items/custritm.cxx svl/source/items/dateitem.cxx svl/source/items/globalnameitem.cxx svl/source/items/ilstitem.cxx svl/source/items/imageitm.cxx svl/source/items/intitem.cxx svl/source/items/itempool.cxx svl/source/items/itemprop.cxx svl/source/items/itemset.cxx svl/source/items/lckbitem.cxx svl/source/items/poolio.cxx svl/source/items/poolitem.cxx svl/source/items/ptitem.cxx svl/source/items/rectitem.cxx svl/source/items/slstitm.cxx svl/source/items/srchitem.cxx svl/source/items/style.cxx svl/source/items/szitem.cxx svl/source/items/visitem.cxx svl/source/items/whiter.cxx svl/source/memtools/svarray.cxx svl/source/misc/PasswordHelper.cxx svl/source/misc/adrparse.cxx svl/source/misc/lngmisc.cxx svl/source/notify/brdcst.cxx svl/source/notify/listener.cxx svl/source/notify/listenerbase.cxx svl/source/numbers/makefile.mk svl/source/numbers/nbdll.cxx svl/source/numbers/zforfind.cxx svl/source/numbers/zforlist.cxx svl/source/numbers/zformat.cxx svl/source/numbers/zforscan.cxx svl/source/passwordcontainer/passwordcontainer.cxx svl/source/svdde/ddecli.cxx svl/source/svdde/ddeimp.hxx svl/source/svdde/ddemlos2.h svl/source/svdde/ddesvr.cxx svl/source/undo/undo.cxx svl/source/uno/registerservices.cxx svl/util/makefile.mk svtools/bmpmaker/bmpsum.cxx svtools/bmpmaker/g2g.cxx svtools/bmpmaker/makefile.mk svtools/inc/borderhelper.hxx svtools/inc/svtools/accessiblefactory.hxx svtools/inc/svtools/apearcfg.hxx svtools/inc/svtools/brwbox.hxx svtools/inc/svtools/ctrlbox.hxx svtools/inc/svtools/ctrltool.hxx svtools/inc/svtools/editbrowsebox.hxx svtools/inc/svtools/ehdl.hxx svtools/inc/svtools/embedhlp.hxx svtools/inc/svtools/filter.hxx svtools/inc/svtools/ivctrl.hxx svtools/inc/svtools/parhtml.hxx svtools/inc/svtools/printdlg.hxx svtools/inc/svtools/rtftoken.h svtools/inc/svtools/ruler.hxx svtools/inc/svtools/svicnvw.hxx svtools/inc/svtools/svlbitm.hxx svtools/inc/svtools/svlbox.hxx svtools/inc/svtools/svtreebx.hxx svtools/inc/svtools/tabbar.hxx svtools/inc/svtools/table/abstracttablecontrol.hxx svtools/inc/svtools/taskbar.hxx svtools/inc/svtools/textview.hxx svtools/inc/svtools/valueset.hxx svtools/source/brwbox/brwbox1.cxx svtools/source/brwbox/brwbox2.cxx svtools/source/brwbox/datwin.cxx svtools/source/brwbox/datwin.hxx svtools/source/brwbox/makefile.mk svtools/source/config/apearcfg.cxx svtools/source/config/htmlcfg.cxx svtools/source/config/menuoptions.cxx svtools/source/config/miscopt.cxx svtools/source/contnr/cont_pch.cxx svtools/source/contnr/ctrdll.cxx svtools/source/contnr/fileview.cxx svtools/source/contnr/imivctl1.cxx svtools/source/contnr/ivctrl.cxx svtools/source/contnr/makefile.mk svtools/source/contnr/svcontnr.src svtools/source/contnr/svicnvw.cxx svtools/source/contnr/svimpbox.cxx svtools/source/contnr/svimpicn.cxx svtools/source/contnr/svlbitm.cxx svtools/source/contnr/svtreebx.cxx svtools/source/contnr/templwin.cxx svtools/source/contnr/templwin.hxx svtools/source/control/asynclink.cxx svtools/source/control/ctrlbox.cxx svtools/source/control/ctrldll.cxx svtools/source/control/ctrltool.cxx svtools/source/control/filectrl.cxx svtools/source/control/filectrl.src svtools/source/control/headbar.cxx svtools/source/control/inettbc.cxx svtools/source/control/makefile.mk svtools/source/control/prgsbar.cxx svtools/source/control/roadmap.cxx svtools/source/control/ruler.cxx svtools/source/control/scriptedtext.cxx svtools/source/control/stdmenu.cxx svtools/source/control/tabbar.cxx svtools/source/control/taskbar.cxx svtools/source/control/taskbox.cxx svtools/source/control/taskmisc.cxx svtools/source/control/taskstat.cxx svtools/source/control/valueacc.cxx svtools/source/control/valueset.cxx svtools/source/dialogs/addresstemplate.cxx svtools/source/dialogs/addresstemplate.src svtools/source/dialogs/colrdlg.src svtools/source/dialogs/filedlg2.cxx svtools/source/dialogs/filedlg2.hxx svtools/source/dialogs/makefile.mk svtools/source/dialogs/printdlg.cxx svtools/source/dialogs/printdlg.src svtools/source/dialogs/propctrl.cxx svtools/source/dialogs/propctrl.hxx svtools/source/dialogs/property.cxx svtools/source/edit/makefile.mk svtools/source/edit/sychconv.cxx svtools/source/edit/syntaxhighlight.cxx svtools/source/edit/textdoc.cxx svtools/source/edit/texteng.cxx svtools/source/edit/textundo.cxx svtools/source/edit/textview.cxx svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx svtools/source/filter.vcl/filter/dlgejpg.cxx svtools/source/filter.vcl/filter/dlgejpg.hxx svtools/source/filter.vcl/filter/dlgejpg.src svtools/source/filter.vcl/filter/dlgepng.cxx svtools/source/filter.vcl/filter/dlgepng.hxx svtools/source/filter.vcl/filter/dlgepng.src svtools/source/filter.vcl/filter/dlgexpor.cxx svtools/source/filter.vcl/filter/dlgexpor.hxx svtools/source/filter.vcl/filter/dlgexpor.src svtools/source/filter.vcl/filter/filter2.cxx svtools/source/filter.vcl/filter/makefile.mk svtools/source/filter.vcl/filter/sgfbram.cxx svtools/source/filter.vcl/filter/sgvmain.cxx svtools/source/filter.vcl/filter/sgvspln.cxx svtools/source/filter.vcl/filter/strings.src svtools/source/filter.vcl/jpeg/makefile.mk svtools/source/filter.vcl/wmf/emfwr.cxx svtools/source/filter.vcl/wmf/emfwr.hxx svtools/source/filter.vcl/wmf/enhwmf.cxx svtools/source/filter.vcl/wmf/winmtf.hxx svtools/source/filter.vcl/wmf/wmfwr.cxx svtools/source/filter.vcl/wmf/wmfwr.hxx svtools/source/graphic/grfcache.cxx svtools/source/graphic/grfcache.hxx svtools/source/graphic/grfmgr.cxx svtools/source/graphic/makefile.mk svtools/source/inc/accessibletableimp.hxx svtools/source/inc/svimpbox.hxx svtools/source/java/patchjavaerror.src svtools/source/misc/ehdl.cxx svtools/source/misc/errtxt.src svtools/source/misc/helpagentwindow.cxx svtools/source/misc/imagemgr.cxx svtools/source/misc/imagemgr.src svtools/source/misc/imageresourceaccess.cxx svtools/source/misc/imap.cxx svtools/source/misc/langtab.src svtools/source/misc/makefile.mk svtools/source/misc/svtdata.cxx svtools/source/misc/templatefoldercache.cxx svtools/source/misc/transfer2.cxx svtools/source/misc/undo.src svtools/source/plugapp/commtest.cxx svtools/source/plugapp/commtest.src svtools/source/plugapp/makefile.mk svtools/source/plugapp/testtool.src svtools/source/productregistration/productregistration.cxx svtools/source/svhtml/htmlkywd.cxx svtools/source/svhtml/parhtml.cxx svtools/source/svrtf/rtfkey2.cxx svtools/source/svrtf/rtfkeywd.cxx svtools/source/table/defaultinputhandler.cxx svtools/source/table/makefile.mk svtools/source/table/tablecontrol.cxx svtools/source/table/tablecontrol_impl.cxx svtools/source/table/tablecontrol_impl.hxx svtools/source/table/tabledatawindow.cxx svtools/source/table/tablegeometry.cxx svtools/source/table/tablegeometry.hxx svtools/source/toolpanel/makefile.mk svtools/source/toolpanel/toolpaneldrawer.cxx svtools/source/uno/addrtempuno.cxx svtools/source/uno/miscservices.cxx svtools/source/uno/svtxgridcontrol.cxx svtools/source/uno/svtxgridcontrol.hxx svtools/source/uno/toolboxcontroller.cxx svtools/source/uno/treecontrolpeer.cxx svtools/source/uno/unocontroltablemodel.cxx svtools/source/uno/unocontroltablemodel.hxx svtools/source/uno/unoimap.cxx svtools/source/urlobj/inetimg.cxx svtools/util/makefile.mk svtools/workben/browser.cxx svtools/workben/cui/makefile.mk svtools/workben/makefile.mk svtools/workben/stest.cxx svtools/workben/toolpanel/makefile.mk svtools/workben/urange.cxx toolkit/inc/toolkit/awt/vclxdevice.hxx toolkit/inc/toolkit/awt/vclxgraphics.hxx toolkit/inc/toolkit/awt/vclxwindows.hxx toolkit/inc/toolkit/controls/dialogcontrol.hxx toolkit/inc/toolkit/helper/property.hxx toolkit/inc/toolkit/helper/servicenames.hxx toolkit/inc/toolkit/helper/throbberimpl.hxx toolkit/qa/complex/toolkit/accessibility/_XAccessibleComponent.java toolkit/source/awt/asynccallback.cxx toolkit/source/awt/vclxgraphics.cxx toolkit/source/awt/vclxtoolkit.cxx toolkit/source/awt/vclxwindow.cxx toolkit/source/awt/xsimpleanimation.cxx toolkit/source/awt/xthrobber.cxx toolkit/source/controls/dialogcontrol.cxx toolkit/source/controls/grid/defaultgridcolumnmodel.cxx toolkit/source/controls/grid/defaultgriddatamodel.cxx toolkit/source/controls/grid/gridcontrol.cxx toolkit/source/controls/grid/initguard.hxx toolkit/source/controls/unocontrol.cxx toolkit/source/controls/unocontrolcontainer.cxx toolkit/source/controls/unocontrols.cxx toolkit/source/helper/listenermultiplexer.cxx toolkit/source/helper/property.cxx toolkit/source/helper/registerservices.cxx toolkit/source/helper/servicenames.cxx toolkit/source/helper/throbberimpl.cxx toolkit/source/helper/tkresmgr.cxx tools/StaticLibrary_ooopathutils.mk tools/bootstrp/addexes/makefile.mk tools/bootstrp/addexes2/makefile.mk tools/bootstrp/addexes2/mkfilt.cxx tools/bootstrp/command.cxx tools/bootstrp/cppdep.cxx tools/bootstrp/iserver.cxx tools/bootstrp/makefile.mk tools/bootstrp/mkcreate.cxx tools/bootstrp/prj.cxx tools/bootstrp/rscdep.cxx tools/bootstrp/sstring.cxx tools/inc/bootstrp/command.hxx tools/inc/bootstrp/mkcreate.hxx tools/inc/bootstrp/prj.hxx tools/inc/bootstrp/sstring.hxx tools/inc/tools/agapi.hxx tools/inc/tools/agitem.hxx tools/inc/tools/chapi.hxx tools/inc/tools/download.hxx tools/inc/tools/eacopier.hxx tools/inc/tools/fract.hxx tools/inc/tools/fsys.hxx tools/inc/tools/geninfo.hxx tools/inc/tools/globname.hxx tools/inc/tools/inetmime.hxx tools/inc/tools/multisel.hxx tools/inc/tools/poly.hxx tools/inc/tools/postsys.h tools/inc/tools/postwin.h tools/inc/tools/presys.h tools/inc/tools/prewin.h tools/inc/tools/pstm.hxx tools/inc/tools/ref.hxx tools/inc/tools/simplerm.hxx tools/inc/tools/solar.h tools/inc/tools/table.hxx tools/inc/tools/urlkeys.hxx tools/inc/tools/urlobj.hxx tools/prj/build.lst tools/prj/d.lst tools/qa/makefile.mk tools/source/communi/geninfo.cxx tools/source/debug/debug.cxx tools/source/fsys/dirent.cxx tools/source/fsys/tdir.cxx tools/source/fsys/unx.cxx tools/source/fsys/urlobj.cxx tools/source/generic/color.cxx tools/source/generic/config.cxx tools/source/generic/fract.cxx tools/source/inet/inetmime.cxx tools/source/memtools/multisel.cxx tools/source/memtools/table.cxx tools/source/rc/resmgr.cxx tools/source/ref/globname.cxx tools/source/ref/pstm.cxx tools/source/solar/solar.c tools/source/stream/strmos2.cxx tools/source/stream/strmunx.cxx tools/source/stream/strmwnt.cxx tools/source/string/makefile.mk tools/source/testtoolloader/testtoolloader.cxx tools/test/makefile.mk tools/util/makefile.mk tools/win/inc/dll.hxx tools/win/inc/parser.hxx tools/win/inc/shellex.h tools/win/inc/shutil.h tools/win/inc/toolsdll.hxx tools/win/inc/winshell.hxx tools/workben/makefile.mk ucbhelper/source/client/proxydecider.cxx ucbhelper/workben/ucbexplorer/ucbexplorer.hrc unotools/inc/unotools/unotunnelhelper.hxx unotools/source/config/fltrcfg.cxx unotools/source/config/lingucfg.cxx unotools/source/config/misccfg.cxx unotools/source/config/pathoptions.cxx unotools/source/config/searchopt.cxx unotools/source/i18n/localedatawrapper.cxx unotools/source/ucbhelper/localfilehelper.cxx unotools/source/ucbhelper/ucbhelper.cxx unotools/source/ucbhelper/xtempfile.cxx vcl/aqua/inc/salbmp.h vcl/aqua/inc/salgdi.h vcl/aqua/inc/salinst.h vcl/aqua/source/app/salinst.cxx vcl/aqua/source/gdi/aquaprintaccessoryview.mm vcl/aqua/source/gdi/salgdi.cxx vcl/aqua/source/gdi/salprn.cxx vcl/aqua/source/window/salframeview.mm vcl/aqua/source/window/salobj.cxx vcl/inc/vcl/bitmap.hxx vcl/inc/vcl/brdwin.hxx vcl/inc/vcl/button.hxx vcl/inc/vcl/cmdevt.hxx vcl/inc/vcl/cvtgrf.hxx vcl/inc/vcl/dialog.hxx vcl/inc/vcl/dockwin.hxx vcl/inc/vcl/event.hxx vcl/inc/vcl/fixed.hxx vcl/inc/vcl/fldunit.hxx vcl/inc/vcl/floatwin.hxx vcl/inc/vcl/gdimtf.hxx vcl/inc/vcl/glyphcache.hxx vcl/inc/vcl/graphite_adaptors.hxx vcl/inc/vcl/graphite_features.hxx vcl/inc/vcl/graphite_layout.hxx vcl/inc/vcl/ilstbox.hxx vcl/inc/vcl/image.h vcl/inc/vcl/imgctrl.hxx vcl/inc/vcl/impbmpconv.hxx vcl/inc/vcl/impprn.hxx vcl/inc/vcl/jobset.h vcl/inc/vcl/keycodes.hxx vcl/inc/vcl/lstbox.hxx vcl/inc/vcl/mapunit.hxx vcl/inc/vcl/menu.hxx vcl/inc/vcl/msgbox.hxx vcl/inc/vcl/outdev.hxx vcl/inc/vcl/prndlg.hxx vcl/inc/vcl/salatype.hxx vcl/inc/vcl/salbmp.hxx vcl/inc/vcl/salgdi.hxx vcl/inc/vcl/salinst.hxx vcl/inc/vcl/seleng.hxx vcl/inc/vcl/settings.hxx vcl/inc/vcl/smartid.hxx vcl/inc/vcl/status.hxx vcl/inc/vcl/strhelper.hxx vcl/inc/vcl/svapp.hxx vcl/inc/vcl/svdata.hxx vcl/inc/vcl/syschild.hxx vcl/inc/vcl/sysdata.hxx vcl/inc/vcl/taskpanelist.hxx vcl/inc/vcl/toolbox.hxx vcl/inc/vcl/vclevent.hxx vcl/inc/vcl/windata.hxx vcl/inc/vcl/window.hxx vcl/inc/vcl/wintypes.hxx vcl/os2/source/app/salinst.cxx vcl/os2/source/gdi/salgdi.cxx vcl/os2/source/window/salmenu.cxx vcl/os2/source/window/salobj.cxx vcl/prj/build.lst vcl/source/app/dbggui.cxx vcl/source/app/help.cxx vcl/source/app/idlemgr.cxx vcl/source/app/settings.cxx vcl/source/app/svapp.cxx vcl/source/app/svdata.cxx vcl/source/app/svmain.cxx vcl/source/app/svmainhook.cxx vcl/source/app/unohelp.cxx vcl/source/app/vclevent.cxx vcl/source/control/button.cxx vcl/source/control/combobox.cxx vcl/source/control/edit.cxx vcl/source/control/field.cxx vcl/source/control/fixed.cxx vcl/source/control/ilstbox.cxx vcl/source/control/imgctrl.cxx vcl/source/control/makefile.mk vcl/source/control/tabctrl.cxx vcl/source/gdi/bitmap.cxx vcl/source/gdi/bitmap2.cxx vcl/source/gdi/bitmap4.cxx vcl/source/gdi/bmpconv.cxx vcl/source/gdi/cvtsvm.cxx vcl/source/gdi/font.cxx vcl/source/gdi/gdimtf.cxx vcl/source/gdi/image.cxx vcl/source/gdi/impimage.cxx vcl/source/gdi/jobset.cxx vcl/source/gdi/makefile.mk vcl/source/gdi/metaact.cxx vcl/source/gdi/outdev.cxx vcl/source/gdi/outdev3.cxx vcl/source/gdi/outdev4.cxx vcl/source/gdi/outdevnative.cxx vcl/source/gdi/pdfwriter.cxx vcl/source/gdi/pdfwriter_impl.cxx vcl/source/gdi/print3.cxx vcl/source/gdi/salmisc.cxx vcl/source/glyphs/gcach_ftyp.cxx vcl/source/glyphs/gcach_ftyp.hxx vcl/source/glyphs/glyphcache.cxx vcl/source/glyphs/graphite_cache.cxx vcl/source/glyphs/graphite_layout.cxx vcl/source/glyphs/graphite_textsrc.hxx vcl/source/helper/canvasbitmap.cxx vcl/source/helper/smartid.cxx vcl/source/helper/xconnection.cxx vcl/source/src/btntext.src vcl/source/src/images.src vcl/source/src/print.src vcl/source/window/accel.cxx vcl/source/window/accmgr.cxx vcl/source/window/brdwin.cxx vcl/source/window/btndlg.cxx vcl/source/window/dlgctrl.cxx vcl/source/window/javachild.cxx vcl/source/window/menu.cxx vcl/source/window/msgbox.cxx vcl/source/window/printdlg.cxx vcl/source/window/status.cxx vcl/source/window/syschild.cxx vcl/source/window/toolbox.cxx vcl/source/window/toolbox2.cxx vcl/source/window/window.cxx vcl/source/window/window2.cxx vcl/source/window/wrkwin.cxx vcl/unx/gtk/app/gtkdata.cxx vcl/unx/gtk/app/gtkinst.cxx vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx vcl/unx/gtk/window/gtkframe.cxx vcl/unx/gtk/window/gtkobject.cxx vcl/unx/headless/svpbmp.hxx vcl/unx/headless/svpgdi.cxx vcl/unx/headless/svpgdi.hxx vcl/unx/headless/svpinst.cxx vcl/unx/headless/svpinst.hxx vcl/unx/headless/svpprn.cxx vcl/unx/headless/svpprn.hxx vcl/unx/headless/svppspgraphics.cxx vcl/unx/headless/svppspgraphics.hxx vcl/unx/headless/svptext.cxx vcl/unx/inc/dtint.hxx vcl/unx/inc/plugins/gtk/gtkdata.hxx vcl/unx/inc/pspgraphics.h vcl/unx/inc/salbmp.h vcl/unx/inc/saldata.hxx vcl/unx/inc/saldisp.hxx vcl/unx/inc/salgdi.h vcl/unx/inc/salinst.h vcl/unx/inc/xfont.hxx vcl/unx/kde/kdedata.cxx vcl/unx/kde4/KDESalGraphics.cxx vcl/unx/source/app/keysymnames.cxx vcl/unx/source/app/saldata.cxx vcl/unx/source/app/saldisp.cxx vcl/unx/source/app/salinst.cxx vcl/unx/source/app/wmadaptor.cxx vcl/unx/source/dtrans/X11_selection.cxx vcl/unx/source/dtrans/X11_service.cxx vcl/unx/source/gdi/makefile.mk vcl/unx/source/gdi/pspgraphics.cxx vcl/unx/source/gdi/salgdi.cxx vcl/unx/source/gdi/salgdi3.cxx vcl/unx/source/gdi/salprnpsp.cxx vcl/unx/source/gdi/xfont.cxx vcl/unx/source/gdi/xlfd_attr.cxx vcl/unx/source/gdi/xlfd_attr.hxx vcl/unx/source/gdi/xlfd_extd.cxx vcl/unx/source/gdi/xlfd_extd.hxx vcl/unx/source/gdi/xlfd_smpl.cxx vcl/unx/source/gdi/xlfd_smpl.hxx vcl/unx/source/printer/ppdparser.cxx vcl/unx/source/printer/printerinfomanager.cxx vcl/unx/source/window/salframe.cxx vcl/unx/source/window/salmenu.cxx vcl/unx/source/window/salobj.cxx vcl/util/makefile2.pmk vcl/win/inc/salbmp.h vcl/win/inc/saldata.hxx vcl/win/inc/salgdi.h vcl/win/inc/salinst.h vcl/win/source/app/saldata.cxx vcl/win/source/app/salinst.cxx vcl/win/source/gdi/salgdi.cxx vcl/win/source/gdi/salgdi3.cxx vcl/win/source/gdi/salprn.cxx vcl/win/source/gdi/winlayout.cxx vcl/win/source/window/salframe.cxx vcl/win/source/window/salobj.cxx vcl/workben/outdevgrind.cxx vos/inc/vos/execabl.hxx vos/inc/vos/macros.hxx vos/inc/vos/pipe.hxx vos/inc/vos/process.hxx vos/inc/vos/refernce.hxx vos/inc/vos/signal.hxx vos/inc/vos/socket.hxx vos/inc/vos/stream.hxx vos/inc/vos/thread.hxx vos/source/pipe.cxx vos/source/process.cxx vos/source/signal.cxx vos/source/thread.cxx vos/source/timer.cxx
1304 lines
42 KiB
C++
1304 lines
42 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_vcl.hxx"
|
|
|
|
#include <tools/zcodec.hxx>
|
|
#include <tools/stream.hxx>
|
|
#include <vcl/salbtype.hxx>
|
|
#include <vcl/bmpacc.hxx>
|
|
#include <vcl/outdev.hxx>
|
|
#include <vcl/bitmap.hxx>
|
|
|
|
#include <utility>
|
|
|
|
|
|
// -----------
|
|
// - Defines -
|
|
// -----------
|
|
|
|
#define DIBCOREHEADERSIZE ( 12UL )
|
|
#define DIBINFOHEADERSIZE ( sizeof( DIBInfoHeader ) )
|
|
#define BITMAPINFOHEADER 0x28
|
|
|
|
#define SETPIXEL4( pBuf, nX, cChar )( (pBuf)[ (nX) >> 1 ] |= ( (nX) & 1 ) ? ( cChar ): (cChar) << 4 );
|
|
|
|
// ----------------------
|
|
// - Compression defines
|
|
// ----------------------
|
|
|
|
#define COMPRESS_OWN ('S'|('D'<<8UL))
|
|
#define COMPRESS_NONE ( 0UL )
|
|
#define RLE_8 ( 1UL )
|
|
#define RLE_4 ( 2UL )
|
|
#define BITFIELDS ( 3UL )
|
|
#define ZCOMPRESS ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */
|
|
|
|
// -----------------
|
|
// - DIBInfoHeader -
|
|
// -----------------
|
|
|
|
struct DIBInfoHeader
|
|
{
|
|
sal_uInt32 nSize;
|
|
sal_Int32 nWidth;
|
|
sal_Int32 nHeight;
|
|
sal_uInt16 nPlanes;
|
|
sal_uInt16 nBitCount;
|
|
sal_uInt32 nCompression;
|
|
sal_uInt32 nSizeImage;
|
|
sal_Int32 nXPelsPerMeter;
|
|
sal_Int32 nYPelsPerMeter;
|
|
sal_uInt32 nColsUsed;
|
|
sal_uInt32 nColsImportant;
|
|
|
|
DIBInfoHeader() :
|
|
nSize( 0UL ),
|
|
nWidth( 0UL ),
|
|
nHeight( 0UL ),
|
|
nPlanes( 0 ),
|
|
nBitCount( 0 ),
|
|
nCompression( 0 ),
|
|
nSizeImage( 0 ),
|
|
nXPelsPerMeter( 0UL ),
|
|
nYPelsPerMeter( 0UL ),
|
|
nColsUsed( 0UL ),
|
|
nColsImportant( 0UL ) {}
|
|
|
|
~DIBInfoHeader() {}
|
|
};
|
|
|
|
namespace
|
|
{
|
|
inline sal_uInt16 discretizeBitcount( sal_uInt16 nInputCount )
|
|
{
|
|
return ( nInputCount <= 1 ) ? 1 :
|
|
( nInputCount <= 4 ) ? 4 :
|
|
( nInputCount <= 8 ) ? 8 : 24;
|
|
}
|
|
|
|
inline bool isBitfieldCompression( sal_uLong nScanlineFormat )
|
|
{
|
|
return nScanlineFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ||
|
|
nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK;
|
|
}
|
|
}
|
|
|
|
// ----------
|
|
// - Bitmap -
|
|
// ----------
|
|
|
|
SvStream& operator>>( SvStream& rIStm, Bitmap& rBitmap )
|
|
{
|
|
rBitmap.Read( rIStm, sal_True );
|
|
return rIStm;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
SvStream& operator<<( SvStream& rOStm, const Bitmap& rBitmap )
|
|
{
|
|
rBitmap.Write( rOStm, sal_False, sal_True );
|
|
return rOStm;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::Read( SvStream& rIStm, sal_Bool bFileHeader, sal_Bool bIsMSOFormat )
|
|
{
|
|
const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt();
|
|
const sal_uLong nOldPos = rIStm.Tell();
|
|
sal_uLong nOffset = 0UL;
|
|
sal_Bool bRet = sal_False;
|
|
|
|
rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
|
|
|
|
if( bFileHeader )
|
|
{
|
|
if( ImplReadDIBFileHeader( rIStm, nOffset ) )
|
|
bRet = ImplReadDIB( rIStm, *this, nOffset );
|
|
}
|
|
else
|
|
bRet = ImplReadDIB( rIStm, *this, nOffset, bIsMSOFormat );
|
|
|
|
if( !bRet )
|
|
{
|
|
if( !rIStm.GetError() )
|
|
rIStm.SetError( SVSTREAM_GENERALERROR );
|
|
|
|
rIStm.Seek( nOldPos );
|
|
}
|
|
|
|
rIStm.SetNumberFormatInt( nOldFormat );
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, sal_uLong nOffset, sal_Bool bIsMSOFormat )
|
|
{
|
|
DIBInfoHeader aHeader;
|
|
const sal_uLong nStmPos = rIStm.Tell();
|
|
sal_Bool bRet = sal_False;
|
|
sal_Bool bTopDown = sal_False;
|
|
|
|
if( ImplReadDIBInfoHeader( rIStm, aHeader, bTopDown, bIsMSOFormat ) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount )
|
|
{
|
|
const sal_uInt16 nBitCount( discretizeBitcount(aHeader.nBitCount) );
|
|
|
|
const Size aSizePixel( aHeader.nWidth, abs(aHeader.nHeight) );
|
|
BitmapPalette aDummyPal;
|
|
Bitmap aNewBmp( aSizePixel, nBitCount, &aDummyPal );
|
|
BitmapWriteAccess* pAcc = aNewBmp.AcquireWriteAccess();
|
|
|
|
if( pAcc )
|
|
{
|
|
sal_uInt16 nColors;
|
|
SvStream* pIStm;
|
|
SvMemoryStream* pMemStm = NULL;
|
|
sal_uInt8* pData = NULL;
|
|
|
|
if( nBitCount <= 8 )
|
|
{
|
|
if( aHeader.nColsUsed )
|
|
nColors = (sal_uInt16) aHeader.nColsUsed;
|
|
else
|
|
nColors = ( 1 << aHeader.nBitCount );
|
|
}
|
|
else
|
|
nColors = 0;
|
|
|
|
if( ZCOMPRESS == aHeader.nCompression )
|
|
{
|
|
ZCodec aCodec;
|
|
sal_uInt32 nCodedSize, nUncodedSize;
|
|
sal_uLong nCodedPos;
|
|
|
|
// read coding information
|
|
rIStm >> nCodedSize >> nUncodedSize >> aHeader.nCompression;
|
|
pData = (sal_uInt8*) rtl_allocateMemory( nUncodedSize );
|
|
|
|
// decode buffer
|
|
nCodedPos = rIStm.Tell();
|
|
aCodec.BeginCompression();
|
|
aCodec.Read( rIStm, pData, nUncodedSize );
|
|
aCodec.EndCompression();
|
|
|
|
// skip unread bytes from coded buffer
|
|
rIStm.SeekRel( nCodedSize - ( rIStm.Tell() - nCodedPos ) );
|
|
|
|
// set decoded bytes to memory stream,
|
|
// from which we will read the bitmap data
|
|
pMemStm = new SvMemoryStream;
|
|
pIStm = pMemStm;
|
|
pMemStm->SetBuffer( (char*) pData, nUncodedSize, sal_False, nUncodedSize );
|
|
nOffset = 0;
|
|
}
|
|
else
|
|
pIStm = &rIStm;
|
|
|
|
// read palette
|
|
if( nColors )
|
|
{
|
|
pAcc->SetPaletteEntryCount( nColors );
|
|
ImplReadDIBPalette( *pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE );
|
|
}
|
|
|
|
// read bits
|
|
if( !pIStm->GetError() )
|
|
{
|
|
if( nOffset )
|
|
pIStm->SeekRel( nOffset - ( pIStm->Tell() - nStmPos ) );
|
|
|
|
bRet = ImplReadDIBBits( *pIStm, aHeader, *pAcc, bTopDown );
|
|
|
|
if( bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter )
|
|
{
|
|
MapMode aMapMode( MAP_MM, Point(),
|
|
Fraction( 1000, aHeader.nXPelsPerMeter ),
|
|
Fraction( 1000, aHeader.nYPelsPerMeter ) );
|
|
|
|
aNewBmp.SetPrefMapMode( aMapMode );
|
|
aNewBmp.SetPrefSize( Size( aHeader.nWidth, abs(aHeader.nHeight) ) );
|
|
}
|
|
}
|
|
|
|
if( pData )
|
|
rtl_freeMemory( pData );
|
|
|
|
delete pMemStm;
|
|
aNewBmp.ReleaseAccess( pAcc );
|
|
|
|
if( bRet )
|
|
rBmp = aNewBmp;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset )
|
|
{
|
|
sal_uInt32 nTmp32;
|
|
sal_uInt16 nTmp16 = 0;
|
|
sal_Bool bRet = sal_False;
|
|
|
|
rIStm >> nTmp16;
|
|
|
|
if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) )
|
|
{
|
|
if ( 0x4142 == nTmp16 )
|
|
{
|
|
rIStm.SeekRel( 12L );
|
|
rIStm >> nTmp16;
|
|
rIStm.SeekRel( 8L );
|
|
rIStm >> nTmp32;
|
|
rOffset = nTmp32 - 28UL;;
|
|
bRet = ( 0x4D42 == nTmp16 );
|
|
}
|
|
else
|
|
{
|
|
rIStm.SeekRel( 8L );
|
|
rIStm >> nTmp32;
|
|
rOffset = nTmp32 - 14UL;
|
|
bRet = ( rIStm.GetError() == 0UL );
|
|
}
|
|
}
|
|
else
|
|
rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader, sal_Bool& bTopDown, sal_Bool bIsMSOFormat )
|
|
{
|
|
// BITMAPINFOHEADER or BITMAPCOREHEADER
|
|
rIStm >> rHeader.nSize;
|
|
|
|
// BITMAPCOREHEADER
|
|
sal_Int16 nTmp16 = 0;
|
|
if ( rHeader.nSize == DIBCOREHEADERSIZE )
|
|
{
|
|
|
|
rIStm >> nTmp16; rHeader.nWidth = nTmp16;
|
|
rIStm >> nTmp16; rHeader.nHeight = nTmp16;
|
|
rIStm >> rHeader.nPlanes;
|
|
rIStm >> rHeader.nBitCount;
|
|
}
|
|
else if ( bIsMSOFormat && ( rHeader.nSize == BITMAPINFOHEADER ) )
|
|
{
|
|
sal_uInt8 nTmp8 = 0;
|
|
rIStm >> nTmp16; rHeader.nWidth = nTmp16;
|
|
rIStm >> nTmp16; rHeader.nHeight = nTmp16;
|
|
rIStm >> nTmp8; rHeader.nPlanes = nTmp8;
|
|
rIStm >> nTmp8; rHeader.nBitCount = nTmp8;
|
|
rIStm >> nTmp16; rHeader.nSizeImage = nTmp16;
|
|
rIStm >> nTmp16; rHeader.nCompression = nTmp16;
|
|
if ( !rHeader.nSizeImage ) // uncompressed?
|
|
rHeader.nSizeImage = ((rHeader.nWidth * rHeader.nBitCount + 31) & ~31) / 8 * rHeader.nHeight;
|
|
rIStm >> rHeader.nXPelsPerMeter;
|
|
rIStm >> rHeader.nYPelsPerMeter;
|
|
rIStm >> rHeader.nColsUsed;
|
|
rIStm >> rHeader.nColsImportant;
|
|
}
|
|
else
|
|
{
|
|
// unknown Header
|
|
if( rHeader.nSize < DIBINFOHEADERSIZE )
|
|
{
|
|
sal_uLong nUnknownSize = sizeof( rHeader.nSize );
|
|
|
|
rIStm >> rHeader.nWidth; nUnknownSize += sizeof( rHeader.nWidth );
|
|
rIStm >> rHeader.nHeight; nUnknownSize += sizeof( rHeader.nHeight );
|
|
rIStm >> rHeader.nPlanes; nUnknownSize += sizeof( rHeader.nPlanes );
|
|
rIStm >> rHeader.nBitCount; nUnknownSize += sizeof( rHeader.nBitCount );
|
|
|
|
if( nUnknownSize < rHeader.nSize )
|
|
{
|
|
rIStm >> rHeader.nCompression;
|
|
nUnknownSize += sizeof( rHeader.nCompression );
|
|
|
|
if( nUnknownSize < rHeader.nSize )
|
|
{
|
|
rIStm >> rHeader.nSizeImage;
|
|
nUnknownSize += sizeof( rHeader.nSizeImage );
|
|
|
|
if( nUnknownSize < rHeader.nSize )
|
|
{
|
|
rIStm >> rHeader.nXPelsPerMeter;
|
|
nUnknownSize += sizeof( rHeader.nXPelsPerMeter );
|
|
|
|
if( nUnknownSize < rHeader.nSize )
|
|
{
|
|
rIStm >> rHeader.nYPelsPerMeter;
|
|
nUnknownSize += sizeof( rHeader.nYPelsPerMeter );
|
|
}
|
|
|
|
if( nUnknownSize < rHeader.nSize )
|
|
{
|
|
rIStm >> rHeader.nColsUsed;
|
|
nUnknownSize += sizeof( rHeader.nColsUsed );
|
|
|
|
if( nUnknownSize < rHeader.nSize )
|
|
{
|
|
rIStm >> rHeader.nColsImportant;
|
|
nUnknownSize += sizeof( rHeader.nColsImportant );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rIStm >> rHeader.nWidth;
|
|
rIStm >> rHeader.nHeight; //rHeader.nHeight=abs(rHeader.nHeight);
|
|
rIStm >> rHeader.nPlanes;
|
|
rIStm >> rHeader.nBitCount;
|
|
rIStm >> rHeader.nCompression;
|
|
rIStm >> rHeader.nSizeImage;
|
|
rIStm >> rHeader.nXPelsPerMeter;
|
|
rIStm >> rHeader.nYPelsPerMeter;
|
|
rIStm >> rHeader.nColsUsed;
|
|
rIStm >> rHeader.nColsImportant;
|
|
}
|
|
|
|
// Eventuell bis zur Palette ueberlesen
|
|
if ( rHeader.nSize > DIBINFOHEADERSIZE )
|
|
rIStm.SeekRel( rHeader.nSize - DIBINFOHEADERSIZE );
|
|
}
|
|
if ( rHeader.nHeight < 0 )
|
|
{
|
|
bTopDown = sal_True;
|
|
rHeader.nHeight *= -1;
|
|
}
|
|
else
|
|
bTopDown = sal_False;
|
|
|
|
if ( rHeader.nWidth < 0 )
|
|
rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
|
|
|
|
// #144105# protect a little against damaged files
|
|
if( rHeader.nSizeImage > ( 16 * static_cast< sal_uInt32 >( rHeader.nWidth * rHeader.nHeight ) ) )
|
|
rHeader.nSizeImage = 0;
|
|
|
|
return( ( rHeader.nPlanes == 1 ) && ( rIStm.GetError() == 0UL ) );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, sal_Bool bQuad )
|
|
{
|
|
const sal_uInt16 nColors = rAcc.GetPaletteEntryCount();
|
|
const sal_uLong nPalSize = nColors * ( bQuad ? 4UL : 3UL );
|
|
BitmapColor aPalColor;
|
|
|
|
sal_uInt8* pEntries = new sal_uInt8[ nPalSize ];
|
|
rIStm.Read( pEntries, nPalSize );
|
|
|
|
sal_uInt8* pTmpEntry = pEntries;
|
|
for( sal_uInt16 i = 0; i < nColors; i++ )
|
|
{
|
|
aPalColor.SetBlue( *pTmpEntry++ );
|
|
aPalColor.SetGreen( *pTmpEntry++ );
|
|
aPalColor.SetRed( *pTmpEntry++ );
|
|
|
|
if( bQuad )
|
|
pTmpEntry++;
|
|
|
|
rAcc.SetPaletteColor( i, aPalColor );
|
|
}
|
|
|
|
delete[] pEntries;
|
|
|
|
return( rIStm.GetError() == 0UL );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc, sal_Bool bTopDown )
|
|
{
|
|
const sal_uLong nAlignedWidth = AlignedWidth4Bytes( rHeader.nWidth * rHeader.nBitCount );
|
|
sal_uInt32 nRMask = 0;
|
|
sal_uInt32 nGMask = 0;
|
|
sal_uInt32 nBMask = 0;
|
|
sal_Bool bNative;
|
|
sal_Bool bTCMask = ( rHeader.nBitCount == 16 ) || ( rHeader.nBitCount == 32 );
|
|
sal_Bool bRLE = ( RLE_8 == rHeader.nCompression && rHeader.nBitCount == 8 ) ||
|
|
( RLE_4 == rHeader.nCompression && rHeader.nBitCount == 4 );
|
|
|
|
// Is native format?
|
|
switch( rAcc.GetScanlineFormat() )
|
|
{
|
|
case( BMP_FORMAT_1BIT_MSB_PAL ):
|
|
case( BMP_FORMAT_4BIT_MSN_PAL ):
|
|
case( BMP_FORMAT_8BIT_PAL ):
|
|
case( BMP_FORMAT_24BIT_TC_BGR ):
|
|
bNative = ( ( rAcc.IsBottomUp() != bTopDown ) && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) );
|
|
break;
|
|
|
|
default:
|
|
bNative = sal_False;
|
|
break;
|
|
}
|
|
// Read data
|
|
if( bNative )
|
|
{
|
|
// true color DIB's can have a (optimization) palette
|
|
if( rHeader.nColsUsed && rHeader.nBitCount > 8 )
|
|
rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) );
|
|
|
|
if ( rHeader.nHeight > 0 )
|
|
rIStm.Read( rAcc.GetBuffer(), rHeader.nHeight * nAlignedWidth );
|
|
else
|
|
{
|
|
for( int i = abs(rHeader.nHeight)-1; i >= 0; i-- )
|
|
rIStm.Read( ((char*)rAcc.GetBuffer()) + (nAlignedWidth*i), nAlignedWidth );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Read color mask
|
|
if( bTCMask )
|
|
{
|
|
if( rHeader.nCompression == BITFIELDS )
|
|
{
|
|
rIStm.SeekRel( -12L );
|
|
rIStm >> nRMask;
|
|
rIStm >> nGMask;
|
|
rIStm >> nBMask;
|
|
}
|
|
else
|
|
{
|
|
nRMask = ( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL;
|
|
nGMask = ( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL;
|
|
nBMask = ( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL;
|
|
}
|
|
}
|
|
|
|
if( bRLE )
|
|
{
|
|
if ( !rHeader.nSizeImage )
|
|
{
|
|
const sal_uLong nOldPos = rIStm.Tell();
|
|
|
|
rIStm.Seek( STREAM_SEEK_TO_END );
|
|
rHeader.nSizeImage = rIStm.Tell() - nOldPos;
|
|
rIStm.Seek( nOldPos );
|
|
}
|
|
|
|
sal_uInt8* pBuffer = (sal_uInt8*) rtl_allocateMemory( rHeader.nSizeImage );
|
|
|
|
rIStm.Read( (char*) pBuffer, rHeader.nSizeImage );
|
|
ImplDecodeRLE( pBuffer, rHeader, rAcc, RLE_4 == rHeader.nCompression );
|
|
|
|
rtl_freeMemory( pBuffer );
|
|
}
|
|
else
|
|
{
|
|
const long nWidth = rHeader.nWidth;
|
|
const long nHeight = abs(rHeader.nHeight);
|
|
sal_uInt8* pBuf = new sal_uInt8[ nAlignedWidth ];
|
|
|
|
// true color DIB's can have a (optimization) palette
|
|
if( rHeader.nColsUsed && rHeader.nBitCount > 8 )
|
|
rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) );
|
|
|
|
const long nI = bTopDown ? 1 : -1;
|
|
long nY = bTopDown ? 0 : nHeight - 1;
|
|
long nCount = nHeight;
|
|
|
|
switch( rHeader.nBitCount )
|
|
{
|
|
case( 1 ):
|
|
{
|
|
sal_uInt8* pTmp;
|
|
sal_uInt8 cTmp;
|
|
|
|
for( ; nCount--; nY += nI )
|
|
{
|
|
rIStm.Read( pTmp = pBuf, nAlignedWidth );
|
|
cTmp = *pTmp++;
|
|
|
|
for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
|
|
{
|
|
if( !nShift )
|
|
{
|
|
nShift = 8L,
|
|
cTmp = *pTmp++;
|
|
}
|
|
|
|
rAcc.SetPixel( nY, nX, sal::static_int_cast<sal_uInt8>(( cTmp >> --nShift ) & 1) );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 4 ):
|
|
{
|
|
sal_uInt8* pTmp;
|
|
sal_uInt8 cTmp;
|
|
|
|
for( ; nCount--; nY += nI )
|
|
{
|
|
rIStm.Read( pTmp = pBuf, nAlignedWidth );
|
|
cTmp = *pTmp++;
|
|
|
|
for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
|
|
{
|
|
if( !nShift )
|
|
{
|
|
nShift = 2UL,
|
|
cTmp = *pTmp++;
|
|
}
|
|
|
|
rAcc.SetPixel( nY, nX, sal::static_int_cast<sal_uInt8>(( cTmp >> ( --nShift << 2UL ) ) & 0x0f) );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 8 ):
|
|
{
|
|
sal_uInt8* pTmp;
|
|
|
|
for( ; nCount--; nY += nI )
|
|
{
|
|
rIStm.Read( pTmp = pBuf, nAlignedWidth );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
rAcc.SetPixel( nY, nX, *pTmp++ );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 16 ):
|
|
{
|
|
ColorMask aMask( nRMask, nGMask, nBMask );
|
|
BitmapColor aColor;
|
|
sal_uInt16* pTmp16;
|
|
|
|
for( ; nCount--; nY += nI )
|
|
{
|
|
rIStm.Read( (char*)( pTmp16 = (sal_uInt16*) pBuf ), nAlignedWidth );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
{
|
|
aMask.GetColorFor16BitLSB( aColor, (sal_uInt8*) pTmp16++ );
|
|
rAcc.SetPixel( nY, nX, aColor );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 24 ):
|
|
{
|
|
BitmapColor aPixelColor;
|
|
sal_uInt8* pTmp;
|
|
|
|
for( ; nCount--; nY += nI )
|
|
{
|
|
rIStm.Read( pTmp = pBuf, nAlignedWidth );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
{
|
|
aPixelColor.SetBlue( *pTmp++ );
|
|
aPixelColor.SetGreen( *pTmp++ );
|
|
aPixelColor.SetRed( *pTmp++ );
|
|
rAcc.SetPixel( nY, nX, aPixelColor );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 32 ):
|
|
{
|
|
ColorMask aMask( nRMask, nGMask, nBMask );
|
|
BitmapColor aColor;
|
|
sal_uInt32* pTmp32;
|
|
|
|
for( ; nCount--; nY += nI )
|
|
{
|
|
rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
{
|
|
aMask.GetColorFor32Bit( aColor, (sal_uInt8*) pTmp32++ );
|
|
rAcc.SetPixel( nY, nX, aColor );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] pBuf;
|
|
}
|
|
}
|
|
|
|
return( rIStm.GetError() == 0UL );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::Write( SvStream& rOStm, sal_Bool bCompressed, sal_Bool bFileHeader ) const
|
|
{
|
|
DBG_ASSERT( mpImpBmp, "Empty Bitmaps can't be saved" );
|
|
|
|
const Size aSizePix( GetSizePixel() );
|
|
sal_Bool bRet = sal_False;
|
|
|
|
if( mpImpBmp && aSizePix.Width() && aSizePix.Height() )
|
|
{
|
|
BitmapReadAccess* pAcc = ( (Bitmap*) this)->AcquireReadAccess();
|
|
const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
|
|
const sal_uLong nOldPos = rOStm.Tell();
|
|
|
|
rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
|
|
|
|
if( pAcc )
|
|
{
|
|
if( bFileHeader )
|
|
{
|
|
if( ImplWriteDIBFileHeader( rOStm, *pAcc ) )
|
|
bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed );
|
|
}
|
|
else
|
|
bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed );
|
|
|
|
( (Bitmap*) this)->ReleaseAccess( pAcc );
|
|
}
|
|
|
|
if( !bRet )
|
|
{
|
|
rOStm.SetError( SVSTREAM_GENERALERROR );
|
|
rOStm.Seek( nOldPos );
|
|
}
|
|
|
|
rOStm.SetNumberFormatInt( nOldFormat );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bCompressed ) const
|
|
{
|
|
const MapMode aMapPixel( MAP_PIXEL );
|
|
DIBInfoHeader aHeader;
|
|
sal_uLong nImageSizePos;
|
|
sal_uLong nEndPos;
|
|
sal_uInt32 nCompression = 0;
|
|
sal_Bool bRet = sal_False;
|
|
|
|
aHeader.nSize = DIBINFOHEADERSIZE;
|
|
aHeader.nWidth = rAcc.Width();
|
|
aHeader.nHeight = rAcc.Height();
|
|
aHeader.nPlanes = 1;
|
|
|
|
if( isBitfieldCompression( rAcc.GetScanlineFormat() ) )
|
|
{
|
|
aHeader.nBitCount = ( rAcc.GetScanlineFormat() == BMP_FORMAT_16BIT_TC_LSB_MASK ) ? 16 : 32;
|
|
aHeader.nSizeImage = rAcc.Height() * rAcc.GetScanlineSize();
|
|
|
|
nCompression = BITFIELDS;
|
|
}
|
|
else
|
|
{
|
|
// #i5xxx# Limit bitcount to 24bit, the 32 bit cases are
|
|
// not handled properly below (would have to set color
|
|
// masks, and nCompression=BITFIELDS - but color mask is
|
|
// not set for formats != *_TC_*). Note that this very
|
|
// problem might cause trouble at other places - the
|
|
// introduction of 32 bit RGBA bitmaps is relatively
|
|
// recent.
|
|
// #i59239# discretize bitcount to 1,4,8,24 (other cases
|
|
// are not written below)
|
|
const sal_uInt16 nBitCount( sal::static_int_cast<sal_uInt16>(rAcc.GetBitCount()) );
|
|
|
|
aHeader.nBitCount = discretizeBitcount( nBitCount );
|
|
aHeader.nSizeImage = rAcc.Height() *
|
|
AlignedWidth4Bytes( rAcc.Width()*aHeader.nBitCount );
|
|
|
|
if( bCompressed )
|
|
{
|
|
if( 4 == nBitCount )
|
|
nCompression = RLE_4;
|
|
else if( 8 == nBitCount )
|
|
nCompression = RLE_8;
|
|
}
|
|
else
|
|
nCompression = COMPRESS_NONE;
|
|
}
|
|
|
|
if( ( rOStm.GetCompressMode() & COMPRESSMODE_ZBITMAP ) &&
|
|
( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_40 ) )
|
|
{
|
|
aHeader.nCompression = ZCOMPRESS;
|
|
}
|
|
else
|
|
aHeader.nCompression = nCompression;
|
|
|
|
if( maPrefSize.Width() && maPrefSize.Height() && ( maPrefMapMode != aMapPixel ) )
|
|
{
|
|
// #i48108# Try to recover xpels/ypels as previously stored on
|
|
// disk. The problem with just converting maPrefSize to 100th
|
|
// mm and then relating that to the bitmap pixel size is that
|
|
// MapMode is integer-based, and suffers from roundoffs,
|
|
// especially if maPrefSize is small. Trying to circumvent
|
|
// that by performing part of the math in floating point.
|
|
const Size aScale100000(
|
|
OutputDevice::LogicToLogic( Size(100000L,
|
|
100000L),
|
|
MAP_100TH_MM,
|
|
maPrefMapMode ) );
|
|
const double fBmpWidthM((double)maPrefSize.Width() / aScale100000.Width() );
|
|
const double fBmpHeightM((double)maPrefSize.Height() / aScale100000.Height() );
|
|
if( fabs(fBmpWidthM) > 0.000000001 &&
|
|
fabs(fBmpHeightM) > 0.000000001 )
|
|
{
|
|
aHeader.nXPelsPerMeter = (sal_uInt32)(rAcc.Width() / fBmpWidthM + .5);
|
|
aHeader.nYPelsPerMeter = (sal_uInt32)(rAcc.Height() / fBmpHeightM + .5);
|
|
}
|
|
}
|
|
|
|
aHeader.nColsUsed = ( ( aHeader.nBitCount <= 8 ) ? rAcc.GetPaletteEntryCount() : 0 );
|
|
aHeader.nColsImportant = 0;
|
|
|
|
rOStm << aHeader.nSize;
|
|
rOStm << aHeader.nWidth;
|
|
rOStm << aHeader.nHeight;
|
|
rOStm << aHeader.nPlanes;
|
|
rOStm << aHeader.nBitCount;
|
|
rOStm << aHeader.nCompression;
|
|
|
|
nImageSizePos = rOStm.Tell();
|
|
rOStm.SeekRel( sizeof( aHeader.nSizeImage ) );
|
|
|
|
rOStm << aHeader.nXPelsPerMeter;
|
|
rOStm << aHeader.nYPelsPerMeter;
|
|
rOStm << aHeader.nColsUsed;
|
|
rOStm << aHeader.nColsImportant;
|
|
|
|
if( aHeader.nCompression == ZCOMPRESS )
|
|
{
|
|
ZCodec aCodec;
|
|
SvMemoryStream aMemStm( aHeader.nSizeImage + 4096, 65535 );
|
|
sal_uLong nCodedPos = rOStm.Tell(), nLastPos;
|
|
sal_uInt32 nCodedSize, nUncodedSize;
|
|
|
|
// write uncoded data palette
|
|
if( aHeader.nColsUsed )
|
|
ImplWriteDIBPalette( aMemStm, rAcc );
|
|
|
|
// write uncoded bits
|
|
bRet = ImplWriteDIBBits( aMemStm, rAcc, nCompression, aHeader.nSizeImage );
|
|
|
|
// get uncoded size
|
|
nUncodedSize = aMemStm.Tell();
|
|
|
|
// seek over compress info
|
|
rOStm.SeekRel( 12 );
|
|
|
|
// write compressed data
|
|
aCodec.BeginCompression( 3 );
|
|
aCodec.Write( rOStm, (sal_uInt8*) aMemStm.GetData(), nUncodedSize );
|
|
aCodec.EndCompression();
|
|
|
|
// update compress info ( coded size, uncoded size, uncoded compression )
|
|
nCodedSize = ( nLastPos = rOStm.Tell() ) - nCodedPos - 12;
|
|
rOStm.Seek( nCodedPos );
|
|
rOStm << nCodedSize << nUncodedSize << nCompression;
|
|
rOStm.Seek( nLastPos );
|
|
|
|
if( bRet )
|
|
bRet = ( rOStm.GetError() == ERRCODE_NONE );
|
|
}
|
|
else
|
|
{
|
|
if( aHeader.nColsUsed )
|
|
ImplWriteDIBPalette( rOStm, rAcc );
|
|
|
|
bRet = ImplWriteDIBBits( rOStm, rAcc, aHeader.nCompression, aHeader.nSizeImage );
|
|
}
|
|
|
|
nEndPos = rOStm.Tell();
|
|
rOStm.Seek( nImageSizePos );
|
|
rOStm << aHeader.nSizeImage;
|
|
rOStm.Seek( nEndPos );
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc )
|
|
{
|
|
sal_uInt32 nPalCount = ( rAcc.HasPalette() ? rAcc.GetPaletteEntryCount() :
|
|
isBitfieldCompression( rAcc.GetScanlineFormat() ) ? 3UL : 0UL );
|
|
sal_uInt32 nOffset = 14 + DIBINFOHEADERSIZE + nPalCount * 4UL;
|
|
|
|
rOStm << (sal_uInt16) 0x4D42;
|
|
rOStm << (sal_uInt32) ( nOffset + ( rAcc.Height() * rAcc.GetScanlineSize() ) );
|
|
rOStm << (sal_uInt16) 0;
|
|
rOStm << (sal_uInt16) 0;
|
|
rOStm << nOffset;
|
|
|
|
return( rOStm.GetError() == 0UL );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc )
|
|
{
|
|
const sal_uInt16 nColors = rAcc.GetPaletteEntryCount();
|
|
const sal_uLong nPalSize = nColors * 4UL;
|
|
sal_uInt8* pEntries = new sal_uInt8[ nPalSize ];
|
|
sal_uInt8* pTmpEntry = pEntries;
|
|
BitmapColor aPalColor;
|
|
|
|
for( sal_uInt16 i = 0; i < nColors; i++ )
|
|
{
|
|
const BitmapColor& rPalColor = rAcc.GetPaletteColor( i );
|
|
|
|
*pTmpEntry++ = rPalColor.GetBlue();
|
|
*pTmpEntry++ = rPalColor.GetGreen();
|
|
*pTmpEntry++ = rPalColor.GetRed();
|
|
*pTmpEntry++ = 0;
|
|
}
|
|
|
|
rOStm.Write( pEntries, nPalSize );
|
|
delete[] pEntries;
|
|
|
|
return( rOStm.GetError() == 0UL );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc,
|
|
sal_uLong nCompression, sal_uInt32& rImageSize )
|
|
{
|
|
if( BITFIELDS == nCompression )
|
|
{
|
|
const ColorMask& rMask = rAcc.GetColorMask();
|
|
SVBT32 aVal32;
|
|
|
|
UInt32ToSVBT32( rMask.GetRedMask(), aVal32 );
|
|
rOStm.Write( (sal_uInt8*) aVal32, 4UL );
|
|
|
|
UInt32ToSVBT32( rMask.GetGreenMask(), aVal32 );
|
|
rOStm.Write( (sal_uInt8*) aVal32, 4UL );
|
|
|
|
UInt32ToSVBT32( rMask.GetBlueMask(), aVal32 );
|
|
rOStm.Write( (sal_uInt8*) aVal32, 4UL );
|
|
|
|
rImageSize = rOStm.Tell();
|
|
|
|
if( rAcc.IsBottomUp() )
|
|
rOStm.Write( rAcc.GetBuffer(), rAcc.Height() * rAcc.GetScanlineSize() );
|
|
else
|
|
{
|
|
for( long nY = rAcc.Height() - 1, nScanlineSize = rAcc.GetScanlineSize(); nY >= 0L; nY-- )
|
|
rOStm.Write( rAcc.GetScanline( nY ), nScanlineSize );
|
|
}
|
|
}
|
|
else if( ( RLE_4 == nCompression ) || ( RLE_8 == nCompression ) )
|
|
{
|
|
rImageSize = rOStm.Tell();
|
|
ImplWriteRLE( rOStm, rAcc, RLE_4 == nCompression );
|
|
}
|
|
else if( !nCompression )
|
|
{
|
|
// #i5xxx# Limit bitcount to 24bit, the 32 bit cases are not
|
|
// handled properly below (would have to set color masks, and
|
|
// nCompression=BITFIELDS - but color mask is not set for
|
|
// formats != *_TC_*). Note that this very problem might cause
|
|
// trouble at other places - the introduction of 32 bit RGBA
|
|
// bitmaps is relatively recent.
|
|
// #i59239# discretize bitcount for aligned width to 1,4,8,24
|
|
// (other cases are not written below)
|
|
const sal_uInt16 nBitCount( sal::static_int_cast<sal_uInt16>(rAcc.GetBitCount()) );
|
|
const sal_uLong nAlignedWidth = AlignedWidth4Bytes( rAcc.Width() *
|
|
discretizeBitcount(nBitCount));
|
|
sal_Bool bNative = sal_False;
|
|
|
|
switch( rAcc.GetScanlineFormat() )
|
|
{
|
|
case( BMP_FORMAT_1BIT_MSB_PAL ):
|
|
case( BMP_FORMAT_4BIT_MSN_PAL ):
|
|
case( BMP_FORMAT_8BIT_PAL ):
|
|
case( BMP_FORMAT_24BIT_TC_BGR ):
|
|
{
|
|
if( rAcc.IsBottomUp() && ( rAcc.GetScanlineSize() == nAlignedWidth ) )
|
|
bNative = sal_True;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
rImageSize = rOStm.Tell();
|
|
|
|
if( bNative )
|
|
rOStm.Write( rAcc.GetBuffer(), nAlignedWidth * rAcc.Height() );
|
|
else
|
|
{
|
|
const long nWidth = rAcc.Width();
|
|
const long nHeight = rAcc.Height();
|
|
sal_uInt8* pBuf = new sal_uInt8[ nAlignedWidth ];
|
|
sal_uInt8* pTmp;
|
|
sal_uInt8 cTmp;
|
|
|
|
switch( nBitCount )
|
|
{
|
|
case( 1 ):
|
|
{
|
|
for( long nY = nHeight - 1; nY >= 0L; nY-- )
|
|
{
|
|
pTmp = pBuf;
|
|
cTmp = 0;
|
|
|
|
for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
|
|
{
|
|
if( !nShift )
|
|
{
|
|
nShift = 8L;
|
|
*pTmp++ = cTmp;
|
|
cTmp = 0;
|
|
}
|
|
|
|
cTmp |= ( (sal_uInt8) rAcc.GetPixel( nY, nX ) << --nShift );
|
|
}
|
|
|
|
*pTmp = cTmp;
|
|
rOStm.Write( pBuf, nAlignedWidth );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 4 ):
|
|
{
|
|
for( long nY = nHeight - 1; nY >= 0L; nY-- )
|
|
{
|
|
pTmp = pBuf;
|
|
cTmp = 0;
|
|
|
|
for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
|
|
{
|
|
if( !nShift )
|
|
{
|
|
nShift = 2L;
|
|
*pTmp++ = cTmp;
|
|
cTmp = 0;
|
|
}
|
|
|
|
cTmp |= ( (sal_uInt8) rAcc.GetPixel( nY, nX ) << ( --nShift << 2L ) );
|
|
}
|
|
*pTmp = cTmp;
|
|
rOStm.Write( pBuf, nAlignedWidth );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case( 8 ):
|
|
{
|
|
for( long nY = nHeight - 1; nY >= 0L; nY-- )
|
|
{
|
|
pTmp = pBuf;
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
*pTmp++ = rAcc.GetPixel( nY, nX );
|
|
|
|
rOStm.Write( pBuf, nAlignedWidth );
|
|
}
|
|
}
|
|
break;
|
|
|
|
// #i59239# fallback to 24 bit format, if bitcount is non-default
|
|
default:
|
|
// FALLTHROUGH intended
|
|
case( 24 ):
|
|
{
|
|
BitmapColor aPixelColor;
|
|
|
|
for( long nY = nHeight - 1; nY >= 0L; nY-- )
|
|
{
|
|
pTmp = pBuf;
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
{
|
|
aPixelColor = rAcc.GetPixel( nY, nX );
|
|
*pTmp++ = aPixelColor.GetBlue();
|
|
*pTmp++ = aPixelColor.GetGreen();
|
|
*pTmp++ = aPixelColor.GetRed();
|
|
}
|
|
|
|
rOStm.Write( pBuf, nAlignedWidth );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
delete[] pBuf;
|
|
}
|
|
}
|
|
|
|
rImageSize = rOStm.Tell() - rImageSize;
|
|
|
|
return( rOStm.GetError() == 0UL );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void Bitmap::ImplDecodeRLE( sal_uInt8* pBuffer, DIBInfoHeader& rHeader,
|
|
BitmapWriteAccess& rAcc, sal_Bool bRLE4 )
|
|
{
|
|
Scanline pRLE = pBuffer;
|
|
long nY = abs(rHeader.nHeight) - 1L;
|
|
const sal_uLong nWidth = rAcc.Width();
|
|
sal_uLong nCountByte;
|
|
sal_uLong nRunByte;
|
|
sal_uLong nX = 0UL;
|
|
sal_uInt8 cTmp;
|
|
sal_Bool bEndDecoding = sal_False;
|
|
|
|
do
|
|
{
|
|
if( ( nCountByte = *pRLE++ ) == 0 )
|
|
{
|
|
nRunByte = *pRLE++;
|
|
|
|
if( nRunByte > 2 )
|
|
{
|
|
if( bRLE4 )
|
|
{
|
|
nCountByte = nRunByte >> 1;
|
|
|
|
for( sal_uLong i = 0UL; i < nCountByte; i++ )
|
|
{
|
|
cTmp = *pRLE++;
|
|
|
|
if( nX < nWidth )
|
|
rAcc.SetPixel( nY, nX++, cTmp >> 4 );
|
|
|
|
if( nX < nWidth )
|
|
rAcc.SetPixel( nY, nX++, cTmp & 0x0f );
|
|
}
|
|
|
|
if( nRunByte & 1 )
|
|
{
|
|
if( nX < nWidth )
|
|
rAcc.SetPixel( nY, nX++, *pRLE >> 4 );
|
|
|
|
pRLE++;
|
|
}
|
|
|
|
if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
|
|
pRLE++;
|
|
}
|
|
else
|
|
{
|
|
for( sal_uLong i = 0UL; i < nRunByte; i++ )
|
|
{
|
|
if( nX < nWidth )
|
|
rAcc.SetPixel( nY, nX++, *pRLE );
|
|
|
|
pRLE++;
|
|
}
|
|
|
|
if( nRunByte & 1 )
|
|
pRLE++;
|
|
}
|
|
}
|
|
else if( !nRunByte )
|
|
{
|
|
nY--;
|
|
nX = 0UL;
|
|
}
|
|
else if( nRunByte == 1 )
|
|
bEndDecoding = sal_True;
|
|
else
|
|
{
|
|
nX += *pRLE++;
|
|
nY -= *pRLE++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cTmp = *pRLE++;
|
|
|
|
if( bRLE4 )
|
|
{
|
|
nRunByte = nCountByte >> 1;
|
|
|
|
for( sal_uLong i = 0UL; i < nRunByte; i++ )
|
|
{
|
|
if( nX < nWidth )
|
|
rAcc.SetPixel( nY, nX++, cTmp >> 4 );
|
|
|
|
if( nX < nWidth )
|
|
rAcc.SetPixel( nY, nX++, cTmp & 0x0f );
|
|
}
|
|
|
|
if( ( nCountByte & 1 ) && ( nX < nWidth ) )
|
|
rAcc.SetPixel( nY, nX++, cTmp >> 4 );
|
|
}
|
|
else
|
|
{
|
|
for( sal_uLong i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ )
|
|
rAcc.SetPixel( nY, nX++, cTmp );
|
|
}
|
|
}
|
|
}
|
|
while ( !bEndDecoding && ( nY >= 0L ) );
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
sal_Bool Bitmap::ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bRLE4 )
|
|
{
|
|
const sal_uLong nWidth = rAcc.Width();
|
|
const sal_uLong nHeight = rAcc.Height();
|
|
sal_uLong nX;
|
|
sal_uLong nSaveIndex;
|
|
sal_uLong nCount;
|
|
sal_uLong nBufCount;
|
|
sal_uInt8* pBuf = new sal_uInt8[ ( nWidth << 1 ) + 2 ];
|
|
sal_uInt8* pTmp;
|
|
sal_uInt8 cPix;
|
|
sal_uInt8 cLast;
|
|
sal_Bool bFound;
|
|
|
|
for ( long nY = nHeight - 1L; nY >= 0L; nY-- )
|
|
{
|
|
pTmp = pBuf;
|
|
nX = nBufCount = 0UL;
|
|
|
|
while( nX < nWidth )
|
|
{
|
|
nCount = 1L;
|
|
cPix = rAcc.GetPixel( nY, nX++ );
|
|
|
|
while( ( nX < nWidth ) && ( nCount < 255L ) && ( cPix == rAcc.GetPixel( nY, nX ) ) )
|
|
{
|
|
nX++;
|
|
nCount++;
|
|
}
|
|
|
|
if ( nCount > 1 )
|
|
{
|
|
*pTmp++ = (sal_uInt8) nCount;
|
|
*pTmp++ = ( bRLE4 ? ( ( cPix << 4 ) | cPix ) : cPix );
|
|
nBufCount += 2;
|
|
}
|
|
else
|
|
{
|
|
cLast = cPix;
|
|
nSaveIndex = nX - 1UL;
|
|
bFound = sal_False;
|
|
|
|
while( ( nX < nWidth ) && ( nCount < 256L ) && ( cPix = rAcc.GetPixel( nY, nX ) ) != cLast )
|
|
{
|
|
nX++; nCount++;
|
|
cLast = cPix;
|
|
bFound = sal_True;
|
|
}
|
|
|
|
if ( bFound )
|
|
nX--;
|
|
|
|
if ( nCount > 3 )
|
|
{
|
|
*pTmp++ = 0;
|
|
*pTmp++ = (sal_uInt8) --nCount;
|
|
|
|
if( bRLE4 )
|
|
{
|
|
for ( sal_uLong i = 0; i < nCount; i++, pTmp++ )
|
|
{
|
|
*pTmp = (sal_uInt8) rAcc.GetPixel( nY, nSaveIndex++ ) << 4;
|
|
|
|
if ( ++i < nCount )
|
|
*pTmp |= rAcc.GetPixel( nY, nSaveIndex++ );
|
|
}
|
|
|
|
nCount = ( nCount + 1 ) >> 1;
|
|
}
|
|
else
|
|
{
|
|
for( sal_uLong i = 0UL; i < nCount; i++ )
|
|
*pTmp++ = rAcc.GetPixel( nY, nSaveIndex++ );
|
|
}
|
|
|
|
if ( nCount & 1 )
|
|
{
|
|
*pTmp++ = 0;
|
|
nBufCount += ( nCount + 3 );
|
|
}
|
|
else
|
|
nBufCount += ( nCount + 2 );
|
|
}
|
|
else
|
|
{
|
|
*pTmp++ = 1;
|
|
*pTmp++ = (sal_uInt8) rAcc.GetPixel( nY, nSaveIndex ) << ( bRLE4 ? 4 : 0 );
|
|
|
|
if ( nCount == 3 )
|
|
{
|
|
*pTmp++ = 1;
|
|
*pTmp++ = (sal_uInt8) rAcc.GetPixel( nY, ++nSaveIndex ) << ( bRLE4 ? 4 : 0 );
|
|
nBufCount += 4;
|
|
}
|
|
else
|
|
nBufCount += 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
pBuf[ nBufCount++ ] = 0;
|
|
pBuf[ nBufCount++ ] = 0;
|
|
|
|
rOStm.Write( pBuf, nBufCount );
|
|
}
|
|
|
|
rOStm << (sal_uInt8) 0;
|
|
rOStm << (sal_uInt8) 1;
|
|
|
|
delete[] pBuf;
|
|
|
|
return( rOStm.GetError() == 0UL );
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|