From cfbe03c9c3ffecd6363dcc63e6fc27b8c6ed70aa Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Sun, 29 Nov 1998 21:16:36 +0000 Subject: [PATCH] Added xpm directory. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1083 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/xpm/changes | 704 +++++++++++++++++++++ src/xpm/copyrigh.t | 31 + src/xpm/crbuffri.c | 324 ++++++++++ src/xpm/crbuffrp.c | 82 +++ src/xpm/crdatfri.c | 304 +++++++++ src/xpm/crdatfrp.c | 83 +++ src/xpm/create.c | 1461 ++++++++++++++++++++++++++++++++++++++++++++ src/xpm/crifrbuf.c | 90 +++ src/xpm/crifrdat.c | 89 +++ src/xpm/crpfrbuf.c | 72 +++ src/xpm/crpfrdat.c | 75 +++ src/xpm/data.c | 627 +++++++++++++++++++ src/xpm/files | 47 ++ src/xpm/hashtab.c | 224 +++++++ src/xpm/misc.c | 572 +++++++++++++++++ src/xpm/parse.c | 704 +++++++++++++++++++++ src/xpm/rdftodat.c | 63 ++ src/xpm/rdftoi.c | 91 +++ src/xpm/rdftop.c | 72 +++ src/xpm/readme | 192 ++++++ src/xpm/readme.msw | 83 +++ src/xpm/rgb.c | 282 +++++++++ src/xpm/rgbtab.h | 292 +++++++++ src/xpm/scan.c | 843 +++++++++++++++++++++++++ src/xpm/simx.c | 284 +++++++++ src/xpm/simx.h | 142 +++++ src/xpm/wrffrdat.c | 58 ++ src/xpm/wrffri.c | 258 ++++++++ src/xpm/wrffrp.c | 83 +++ src/xpm/xpm34.h | 555 +++++++++++++++++ src/xpm/xpm34p.h | 304 +++++++++ 31 files changed, 9091 insertions(+) create mode 100644 src/xpm/changes create mode 100644 src/xpm/copyrigh.t create mode 100644 src/xpm/crbuffri.c create mode 100644 src/xpm/crbuffrp.c create mode 100644 src/xpm/crdatfri.c create mode 100644 src/xpm/crdatfrp.c create mode 100644 src/xpm/create.c create mode 100644 src/xpm/crifrbuf.c create mode 100644 src/xpm/crifrdat.c create mode 100644 src/xpm/crpfrbuf.c create mode 100644 src/xpm/crpfrdat.c create mode 100644 src/xpm/data.c create mode 100644 src/xpm/files create mode 100644 src/xpm/hashtab.c create mode 100644 src/xpm/misc.c create mode 100644 src/xpm/parse.c create mode 100644 src/xpm/rdftodat.c create mode 100644 src/xpm/rdftoi.c create mode 100644 src/xpm/rdftop.c create mode 100644 src/xpm/readme create mode 100644 src/xpm/readme.msw create mode 100644 src/xpm/rgb.c create mode 100644 src/xpm/rgbtab.h create mode 100644 src/xpm/scan.c create mode 100644 src/xpm/simx.c create mode 100644 src/xpm/simx.h create mode 100644 src/xpm/wrffrdat.c create mode 100644 src/xpm/wrffri.c create mode 100644 src/xpm/wrffrp.c create mode 100644 src/xpm/xpm34.h create mode 100644 src/xpm/xpm34p.h diff --git a/src/xpm/changes b/src/xpm/changes new file mode 100644 index 0000000000..1cd0e9a8dd --- /dev/null +++ b/src/xpm/changes @@ -0,0 +1,704 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/**************************************************************************\ +* * +* HISTORY of user-visible changes * +* * +\**************************************************************************/ + +3.4b (94/05/24) + + ENHANCEMENTS: + - XPM can now be built under MS Windows. Yes, this is possible and this + entirely comes from: + - Hermann Dunkel + See the README.MSW file for details. + + - building the shared library now depends on the SharedLibXpm variable + and no longer on the SharedLibX variable which is private to the X + Window System project. + - patch from Stephen Gildea + Other variables can now be set for the various locations needed. + + - lib/parse.c does no longer use a 256x256 array in the stack but + malloc it instead. + + - The Copyright notice which has been re-written from the X11R6's one + should be clearer and is now present in every file. + + BUGS CORRECTED: + - lib/xpmP.h does no longer define a Boolean type which conflicts with + the Intrinsic definition. Instead the type Bool defined in Xlib is + used. + - neumann@watson.ibm.com (Gustaf Neumann) + +3.4a (94/03/29) + + BUGS CORRECTED: + - passing NULL as shapemask_return to XpmReadFileToPixmap and similar + functions was leading to a bus error. + - Dean Luick + +3.4 (94/03/14) + + IMPORTANT NOTE: + This version is not compatible with 3.3. Fortunately most people should + only need to recompile. + I apology for this but CDE/Motif have put heavy pressure to go that + way. The point is that I designed and released Xpm 3.3 in order to let + OSF include a clean version of Xpm in Motif 2.0. This new version was + not fully compatible with 3.2 but I thought it didn't matter since this + was going to be the first version used within Motif. Unfortunately CDE + was already using xpm-3.2 internally and requires both source and + binary backward compatibility. By the way I must say they didn't drop + us a single line to let us know they were using it and thus were + expecting stability. All this could have been avoided... + + However, since I had to go for a not compatible version I took this as + an opportunity to modify the lower level API, which was new in 3.3 and + which was somewhat clumsy, in order to provide yet a better API. + + The library has been modified to have both source and binary backward + compatibility with xpm-3.2. This implies it is not either source or + binary compatible with 3.3. The fields related to the 3.2 XpmInfos + mechanism have been put back into the XpmAttributes structure. The new + 3.3 XpmInfos struct has been renamed as XpmInfo to avoid conflict with + the old 3.2 flag which is back too. All the semantic related to the + XpmAttributes infos fields is back as well. + + So this new version provides a high level API which is fully + compatible with 3.2 and still provides the 3.3 lower level API + (XpmImage) with the XpmInfos struct renamed as XpmInfo. This leads to + some redundancy but this was the best I could do to satisfy both + CDE/Motif people who needed the backward compatibility and myself (who + always tries to provide you with the best ;-). + + Tests have been successfully performed with pixmap-2.1, pixmap-2.4, and + sxpm. + + ENHANCEMENTS: + - The colorTable member of the XpmAttributes structure is now an + (XpmColor*) in order to be compatible with an XpmImage colorTable. + However in order to be backward compatible this field is cast to + (XpmColor **), which is equivalent to (char ***), when it is used + with the old flags XpmInfos and XpmReturnInfos. To handle the new + type the new flags XpmColorTable and XpmReturnColorTable have been + defined. + - The XpmInfo struct has been extended to avoid having to deal with an + XpmAttributes at the lower level. The idea is that all the data + stored in an Xpm file can be retreive through both an XpmImage and + an XpmInfo struct. See the documentation for details. + - XpmUndefPixel is defined and exported by xpm.h in order to let + clients providing their own colorTable when writting out an Xpm file. + See the documentation for details. + - in sxpm/sxpm.c, set attribute XtNinput to True on toplevel widget. + Windows that don't "take" input, never get focus, as mandated by + the ICCM. + patch from Henrique Martins + - lib/Imakefile modified to build the shared library under IRIX 5. + patch from simon@lia.di.epfl.ch (Simon Leinen) + + NEW FEATURES: + - a new funtion and a new define should help client figuring out with + which Xpm library version they are working. These are + XpmIncludeVersion and XpmLibraryVersion(). + +3.3 (93/12/20) + + NEW FEATURES: + - XPM1 files are now supported. + - a new function is provided to get an error string related to the + returned error code. + - suggested by Detlef Schmier + + ENHANCEMENTS: + - gzip and gunzip are called with the -q option (quiet) + - patch from Chris P. Ross + - the parser is again more flexible about the way the strings are + distributed on lines. Actually a single line XPM file can be read. + - the documentation should be clearer about shapemask generation and + XpmAttributes valuemask. + + BUGS CORRECTED: + - reading some binary file was leading to a bus error. + - patch from Detlef Schmier + - the ? character is no longer used when writting an XPM file in order + to avoid possible ANSI trigraphs. + +3.3alpha (93/08/13) + + NEW FEATURES: + - a new level interface is provided to allow applications to do either + icon editing or data caching. + The XpmAttributes has been changed but most applications will just + need to be recompiled. + - new structures are provided to deal with the new lower level: + XpmImage, XpmColor, XpmInfos. + + - a separate distribution called xpm-contrib is available. This + includes the converters which used to be part of this distribution + plus: + two new appplications: + * nexpm to draw a pixmap in *any* existing window from + Ralph Betza + * xpmview to display a list of Xpm files from + Jean Michel Leon + + a hacky string to pixmap converter, provided by + Robert H. Forsman Jr. + + The Xpm editor called pixmap will also be part of this contrib. + This does not mean it is the best pixmap editor one can find + but it is the only one that I know of which tries to handle + all the features of this format. + + ENHANCEMENTS: + - the code to build XImage data has been optimized by + jules@x.co.uk (Julian Gosnell) + the old code is still available when compiling with the + -DWITHOUT_SPEEDUPS flag. + + - closecolor code was not re-entrant + - dbl@visual.com (David B. Lewis) + - fix gzip filename (*.gz and no longer *.z). + - Jason Patterson + - sxpm has 2 new options: + -nom to do not display the mask if there is one + -cp to override a color value with a given + pixel, i.e. sxpm plaid.xpm -cp red 4 + + also the '-s' adn '-p' options have been renamed to '-sc' and '-sp'. + + - xpm.h defines XpmFormat, XpmVersion, and XpmRevision numbers. + + BUGS CORRECTED: + - closecolor minor fix + - Jason Patterson + +3.2g (93/04/26) + + ENHANCEMENTS: + - much faster close colors + - piping from/to compressed files now handles GNU's gzip (.z) format + - added XpmColorKey attribute - ability to specify which visual's + colors to use (ie: now it's possible to read in a pixmap in a + color visual, but use the colors specified for monochrome). + - added -mono, -grey4, -grey and -color options to sxpm to demonstrate + the XpmColorKey attribute. + - Jason Patterson + + BUGS CORRECTED: + - fixed bug where redefining "None" as a pixel stopped mask generation + - minor SVR4 defines for + - fixed annoying closecolor bug related to read/write color cells + - fixed minor bug in color value -> pixel overloading + - manual updated to include new red/green/blue closeness attributes + - Jason Patterson + + - the top Imakefile was missing the depend target + - sxpm/Imakefile fixed so that -L../lib is set before the standard + library location. + - Vivek Khera + + - lib/xpmP.h now defines bcopy as memcpy for VMS (required by recent + versions of VMS) + - J. Daniel Smith + + - the lib/Imakefile didn't work with X11R4. + + +3.2f (93/03/17) + + NEW FEATURES: + - the library provides four new functions to deal with Xpm files + loaded in memory as single character strings buffers: + + XpmCreateImageFromBuffer + XpmCreatePixmapFromBuffer + XpmCreateBufferFromImage + XpmCreateBufferFromPixmap + + - in addition, as a convenience, two functions are provided to copy a + file in a buffer and to write a file from a buffer: + + XpmReadFileToBuffer + XpmWriteFileFromBuffer + + ENHANCEMENTS: + - Files are now dispatched in the following sub-directories: + lib, sxpm, and doc. + - Imakefiles will let you build a shared library as well as the static + one (with either X11R4 or X11R5). + - The documentation has been ported from LaTeX to FrameMaker and is + now included in the distribution in its PostScript form (doc/xpm.ps). + Source files are available on request. + Also the documentation has been reoreganized and includes a table of + contents and an index of the functions (the number of functions + increasing this became a requisite). + + BUGS CORRECTED: + - Many warnings have been fixed - patch from Daniel Dardailler + daniel@osf.org + +3.2e (93/02/05) + + ENHANCEMENTS: + - use XpmMalloc, XpmRealloc, XpmCalloc, and XpmFree which are defines + in xpmP.h. This should help people wanting to use their own functions. + + BUGS CORRECTED: + - Intrinsic.h is no longer included. + - bzero is defined as memset on SYSV and SVR4. + - some memory initialisation bug concerning XpmAttributes. + +3.2d (93/01/27) + + ENHANCEMENTS: + - compile on Solaris 2.0 + - patch from Clint Jeffery + + BUGS CORRECTED: + - shape masks are now set correctly for LSBFirst (Decs). + - pixmaps are now set correctly for 2 bit displays (Nexts). + - patch from Josef Leherbauer + - isspace was called on getc which fails when EOF is returned. + - Marelli Paolo + +3.2c (92/12/29) + + ENHANCEMENTS: + - parsing optimized for single and double characters color + - patch originally from Martin Brunecky + marbru@build1.auto-trol.com + + BUGS CORRECTED: + - XpmFreeExtensions was calling free on some argument without checking + it was not NULL. + - strdup was not correctly defined for systems which do not provide + it. - Hans-Peter Lichtin + - some bug in XpmCrDataFI.c + - Sven Delmas garfield@avalanche.cs.tu-berlin.de + + NOTE: + - there is still a bug with the creation of the clipmask on display of + depth 2 but I can't find a fix because unfortunately I don't have such + a rendering system and nobody gets the time to investigate for me. + +3.2b (92/10/19) + + ENHANCEMENTS: + - Create XpmReadFileToData and XpmWriteFileFromData + - Dan Greening + - added "close colors" support and ability to redefine color values + as pixels at load time, as well as color names + - Jason Patterson + - errors while parsing or allocating colors now revert to other + visual defaults, creating pixmap/image as expected, and returning + XpmSuccess. The old behaviour of XpmColorError being returned and no + pixmap/image being created can be retained by setting the + exactColors attribute. + - Jason Patterson + + BUGS CORRECTED: + - SVR4 defines for including instead of + - Jason Patterson + - attributes->extensions and attributes->nextensions fields were not + set correctly when no extensions present in file. + - Simon_Scott Cornish + +3.2a (92/08/17) + + ENHANCEMENTS: + - use the mock lisp hashing function instead of the gnu emacs one, + it is faster in some cases and never slower (I've not found any case). + + BUGS CORRECTED: + - function prototypes for ansi compilers. + - some memory initialization bugs (purify is just great for this). + - empty strings in extensions are now correctly handled. + +3.2 (92/07/06) + + NEW FEATURES: + - both format and functions handle extensions data. This allow people + to store additional data related to a pixmap. See documentation for + detail. + - sxpm supports the new option '-c' to use a private colormap. This is + useful when displaying pixmaps using a lot of colors. + - sxpm supports the new option '-v' (verbose) to get possible + extensions print out on standard error. + + ENHANCEMENTS: + - most of the code has been reworked to be improved and thus almost + every function is faster. It takes less than 6 seconds of real time on + a sun4 to display, with sxpm, a 487x635 pixmap using 213 colors, while + it takes 32 seconds with the old library! It takes 18 seconds to + display a 1279x1023 screen dump using 14 colors while xwud takes 10 + seconds. + Of course performance improvements are not always that great, they + depend on the size and number of colors but I'm sure everybody will + appreciate ;-) + I know how to improve it more but this will require changes in the + architecture so this is not for now. Some optimizations have been + contributed by gregor@kafka.saic.com (gregg hanna) and + jnc@csl.biosci.arizona.edu (John N. Calley). + - the Imakefile is modified to let you install sxpm - Rainer Klute + + - xpmP.h declares popen for Sequent platforms - Clinton Jeffery + + - XpmWriteFileFromImage/Pixmap rather than truncating the pixmap name + to the first dot changes dots to underscores to get a valid C syntax + name. + + + BUGS CORRECTED: + - there was a bug in the image creation function for some 24 bits + displays. It is fixed. + - allocated color pixels are now freed when an error occurs - + nusser@dec1.wu-wien.ac.at (Stefan Nusser) + + CHANGES TO THE DOC: + - the documentation describes the new XpmExtension structure and how + to use it with read and write functions. + +3.1 (92/02/03) + + ENHANCEMENTS: + - sxpm now have more standard options (mainly suggested by + Rainer Sinkwitz ): + + Usage: sxpm [options...] + Where options are: + + [-d host:display] Display to connect to. + [-g geom] Geometry of window. + [-hints] Set ResizeInc for window. + [-icon filename] Set pixmap for iconWindow. + [-s symbol_name color_name] Overwrite color defaults. + [-p symbol_name pixel_value] Overwrite color defaults. + [-plaid] Read the included plaid pixmap. + [filename] Read from file 'filename', and from + standard input if 'filename' is '-'. + [-o filename] Write to file 'filename', and to standard + output if 'filename' is '-'. + [-nod] Don't display in window. + [-rgb filename] Search color names in the rgb text file + 'filename'. + + if no input is specified sxpm reads from stdandard input. + + + - Xpm functions and Ppm converters now deal with multiword colornames. + patches from Rainer Sinkwitz . + + +3.0 (91/10/03) + + Functions name and defines have been modified again (sorry for that) + as follows: + + XpmReadPixmapFile XpmReadFileToPixmap + XpmWritePixmapFile XpmWriteFileFromPixmap + + XpmPixmapColorError XpmColorError + XpmPixmapSuccess XpmSuccess + XpmPixmapOpenFailed XpmOpenFailed + XpmPixmapFileInvalid XpmFileInvalid + XpmPixmapNoMemory XpmNoMemory + XpmPixmapColorFailed XpmColorFailed + + To update code using Xpm you can use the included shell script called + rename with the sed commands files name-3.0b-3.0c and name-3.0c-3.0. + Old names still valid though. + + NEW FEATURES: + - four new functions to work with images instead of pixmaps: + + XpmReadFileToImage + XpmWriteFileFromImage + XpmCreateImageFromData + XpmCreateDataFromImage + + ENHANCEMENTS: + Algorithms to create and scan images and pixmaps are based on the + MIT's R5 code, thus they are much cleaner than old ones and should + avoid any problem with any visual (yes, I trust MIT folks :-) + + BUGS CORRECTED: + Imakefile use INCDIR instead of ROOTDIR. + + CHANGES TO THE DOC: + - the documentation presents the four new functions. + +3.0c (91/09/18) + + In answer to request of people functions, types and defines names have + been changed as follows: + + XCreatePixmapFromData XpmCreatePixmapFromData + XCreateDataFromPixmap XpmCreateDataFromPixmap + XReadPixmapFile XpmReadPixmapFile + XWritePixmapFile XpmWritePixmapFile + XFreeXpmAttributes XpmFreeAttributes + + PixmapColorError XpmPixmapColorError + PixmapSuccess XpmPixmapSuccess + PixmapOpenFailed XpmPixmapOpenFailed + PixmapFileInvalid XpmPixmapFileInvalid + PixmapNoMemory XpmPixmapNoMemory + PixmapColorFailed XpmPixmapColorFailed + + ColorSymbol XpmColorSymbol + + Generally speaking every public name begins with 'Xpm' and every + private one with 'xpm'. This should avoid any possible conflict. + + Some files have also be renamed accordingly. + + NEW FEATURES: + - support for VMS and two new options for sxpm: icon and hints (see + manual for details) Richard Hess + - DEFINES in Imakefile and Makefile.noXtree allows you to set the + following: + + ZPIPE for un/compressing piped feature (default is on) + NEED_STRCASECMP for system which doesn't provide one (default + is off) + + - xpmtoppm.c has is own strstr function which is used if NEED_STRSTR + is defined when compiling - Hugues.Leroy@irisa.fr (Hugues Leroy). + + BUGS CORRECTED: + - many bugs have been fixed, especially for ansi compilers - + Doyle C. Davidson (doyle@doyled.b23b.ingr.com) and + Clifford D. Morrison (cdm%bigdaddy%edsr@uunet.UU.NET) + - parser is again a little more improved + +3.0b (91/09/12) + + This is a complete new version with a new API and where files and + structures have been renamed. So this should be taken as a new + starting release. + This release should be quickly followed by the 3.0 because I'm planning + to send it for X11R5 contrib which ends October 5th. + + NEW FEATURES: + - support for transparent color. + - support for hotspot. + - a new function: XCreateDataFromPixmap to create an XPM data from a + pixmap in order to be able to create a new pixmap from this data using + the XCreatePixmapFromData function later on. + - a new structure: XpmAttributes which replace the XpmInfo structure + and which leads to a much simpler API with less arguments. + - arguments such as visual, colormap and depth are optionnal, default + values are taken if omitted. + - parsing and allocating color failures don't simply break anymore. If + another default color can be found it is used and a PixmapColorError + is returned. In case no color can be found then it breaks and returns + PixmapColorFailed. + - for this reason the ErrorStatus codes are redefined as follows: + + null if full success + positive if partial success + negative if failure + + with: + #define PixmapColorError 1 + #define PixmapSuccess 0 + #define PixmapOpenFailed -1 + #define PixmapFileInvalid -2 + #define PixmapNoMemory -3 + #define PixmapColorFailed -4 + + - sxpm prints out a warning when a requested color could not be parsed + or alloc'ed, and an error when none has been found. + - sxpm handles pixmap with transparent color. For this purpose the + plaid_mask.xpm is added to the distribution. + + BUGS CORRECTED: + - I've again improved the memory management. + - the parser is also improved. + - when writting a pixmap to a file the variable name could be + "plaid.xpm" which is not valid in C. Now the extension name is cut off + to give "plaid" as variable name. + - reading multiple words colornames such as "peach puff" where leading + to non readable Xpm files. They are now skipped to have only single + word colorname. Lionel Mallet (mallet@ipvpel.unipv.it). + - parser was triggered by the "/" character inside string. + Doyle C. Davidson (doyle@doyled.b23b.ingr.com). This is corrected. + - sxpm maps the window only if the option "-nod" is not selected. + + CHANGES TO THE DOC: + - the documentation presents the new API and features. + +3.0a (91/04/10) + + This is an alpha version because it supports the new version of XPM, + but the library interface is still the same. Indeed it will change in + future release to get rid of obsolete stuff such as the type argument + of the XWritePixmapFile function. + + ******************************* WARNING ********************************* + The format is not anymore XPM2, it is XPM version 3 which is XPM2 + limited to the C syntax with the key word "XPM" in place of "XPM2 C". + The interface library has not changed yet but the type argument of + XWritePixmapFile and the type member of XpmInfo are not used anymore. + Meanwhile the library which is now called libXpm.a is backward + compatible as XPM2 files can be read. But the XWritePixmapFile + function only writes out XPM version 3 files. + ************************************************************************* + + NEW FEATURES: + - the library doesn't use global variables anymore, thus it should be + able to share it. + - sxpm has been rewritten on top of Xt, it can be used to convert + files from XPM2 to XPM version 3. + - xpm1to2c.perl has been upgraded to the new XPM version and renamed + as xpm1to3.perl + - ppmtoxpm2.c and ppmtoxpm2.1 have been upgraded too and renamed + ppmtoxpm.c and ppmtoxpm.1. In addition the xpmtoppm.c and xpmtoppm.1 + of the pbmplus package have been upgraded too. xpmtoppm can thus + convert XPM version 1 and 3 to a portable pixmap. These files should + replace the original ones which are part of the pbmplus package. See + the ppm.README file for more details. + - the library contains RCS variables which allows you to get revision + numbers with ident (which is part of the RCS package). The Id number + is an internal rcs number for my eyes only. The official one is found + in Version. + + BUGS CORRECTED: + - the memory management has been much improved in order to avoid + memory leaks. + - the XImage building algorythm has been changed to support correctly + different visual depths. There is special code to handle depths 1, 4, + 6, 8, 24, and 32 to build the image and send it in one whack, and + other depths are supported by building the image with XPutPixel which + is slow but sure. + - similar algorithms are used to read pixmaps and write them out. + + CHANGES TO THE DOC: + - the documentation presents the new XPM format. + + +2.8 (90/12/19) + + ******************************* WARNING ********************************* + Since the last release two structures have been modified and have now + bigger sizes, so ANY CODE USING THE libXPM2 NEEDS TO BE RECOMPILED. + ************************************************************************* + + NEW FEATURES: + - the ColorSymbol struct contains the new member 'pixel' which allow + to override default colors by giving a pixel value (in such a case + symbol value must be set to NULL), + - the XpmInfo struct contains the new member 'rgb_fname' in which one + can specify an rgb text file name while writing a pixmap with the + XWritePixmapFile function (otherwise this member should be set to + NULL). This way colorname will be searched and written out if found + instead of the RGB value, + - Imakefile originally provided by stolcke@ICSI.Berkeley.EDU, + - the old Makefile is now distributed as Makefile.noXtree and presents + install targets, + - the demo application is renamed sxpm (Show XPM), creates a window of + the size of the pixmap if no geometry is specified, prints out + messages instead of status when an error occurs, handles the new + option -p for overriding colors by giving a pixel value (not really + useful but is just here to show this new feature), handles the new + option -rgb for specifying an rgb text file, and ends on + keypress as buttonpress, + - defines for SYSV have been provided by Paul Breslaw + , + - the distribution includes a new directory called converters which + contains xpm1to2 and xpm1to2c perl converters and a ppmtoxpm2 + converter provided by Paul Breslaw who upgraded the original ppmtoxpm + written by Mark W. Snitily . + + CHANGES TO THE DOC: + - this file is created and will give old users a quick reference to + changes made from one release to the next one, + - documentation is changed to present the new ColorSymbol structure + and the way to override colors by giving a pixel value, and to present + the new XpmInfo structure and how to use it, + - a man page for sxpm is added to the distrib, + - the README file talks about sxpm and no more demo, and have + reference to the different converters. + +2.7 (90/11/12) + + NEW FEATURES: + - XReadPixmapFile reads from stdin if filename is NULL, + - XWritePixmapFile writes to stdin if filename is NULL, + - the demo application handles the new option -nod for no displaying + the pixmap in a window (useful when used as converter). + + CHANGES TO THE DOC: + - documentation about the new feature. + +2.6 (90/10/29) + + NEW FEATURES: + - from nazgul@alphalpha.com (Kee Hinckley): changes to make the + library usable as C++ code, and on Apollo without any warning. + + BUGS CORRECTED: + - from nazgul@alphalpha.com (Kee Hinckley): the xpm include files was + declaring XWritePixmapFile as taking in arg a Pixmap pointer instead + of a Pixmap. + +2.5 (90/10/17) + + BUGS CORRECTED: + - XWritePixmapFile was not closing the file while ending normaly. + +2.4 (90/09/06) + + NEW FEATURES: + - XReadPixmapFile reads from a piped uncompress if the given filename + ends by .Z or if filename.Z exists, + - XWritePixmapFile writes to a piped compress if the given filename + ends by .Z. + + BUGS CORRECTED: + - demo now deals with window manager. + + CHANGES TO THE DOC: + - documentation about compressed files management. + +2.3 (90/08/30) + + BUGS CORRECTED: + - handle monochrom display correctly, + - comments can be empty. + +2.2 (90/08/27) + + BUGS CORRECTED: + - when reading some invalid free was dumping core on some machine. + +2.1 (90/08/24) + + First distribution of XPM2. + diff --git a/src/xpm/copyrigh.t b/src/xpm/copyrigh.t new file mode 100644 index 0000000000..3633944f55 --- /dev/null +++ b/src/xpm/copyrigh.t @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +Arnaud LE HORS BULL Research FRANCE -- Koala Project + (XPM - X PixMap format version 2 & 3) + Internet: lehors@sophia.inria.fr +Surface Mail: Arnaud LE HORS, INRIA - Sophia Antipolis, + 2004, route des Lucioles, 06565 Valbonne Cedex -- FRANCE + Voice phone: (33) 93.65.77.71, Fax: (33) 93 65 77 66, Telex: 97 00 50 F diff --git a/src/xpm/crbuffri.c b/src/xpm/crbuffri.c new file mode 100644 index 0000000000..ed83271ff4 --- /dev/null +++ b/src/xpm/crbuffri.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrBufFrI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM buffer * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include +#else +#include +#endif +#endif + +LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size, + unsigned int *used_size, XpmColor *colors, + unsigned int ncolors, unsigned int cpp)); + +LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size, + unsigned int width, unsigned int height, + unsigned int cpp, unsigned int *pixels, + XpmColor *colors)); + +LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size, + XpmExtension *ext, unsigned int num)); + +LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num)); +LFUNC(CommentsSize, int, (XpmInfo *info)); + +int +XpmCreateBufferFromImage(Display *display, char **buffer_return, XImage *image, + XImage *shapeimage, XpmAttributes *attributes) +{ + XpmImage xpmimage; + XpmInfo info; + int ErrorStatus; + + /* initialize return value */ + if (buffer_return) + *buffer_return = NULL; + + /* create an XpmImage from the image */ + ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage, + &xpmimage, attributes); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the buffer from the XpmImage */ + if (attributes) { + xpmSetInfo(&info, attributes); + ErrorStatus = + XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info); + } else + ErrorStatus = + XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL); + + /* free the XpmImage */ + XpmFreeXpmImage(&xpmimage); + + return (ErrorStatus); +} + + +#undef RETURN +#define RETURN(status) \ +{ \ + if (ptr) \ + XpmFree(ptr); \ + return(status); \ +} + +int +XpmCreateBufferFromXpmImage(char **buffer_return, XpmImage *image, XpmInfo *info) +{ + /* calculation variables */ + int ErrorStatus; + char buf[BUFSIZ]; + unsigned int cmts, extensions, ext_size = 0; + unsigned int l, cmt_size = 0; + char *ptr = NULL, *p; + unsigned int ptr_size, used_size; + + *buffer_return = NULL; + + cmts = info && (info->valuemask & XpmComments); + extensions = info && (info->valuemask & XpmExtensions) + && info->nextensions; + + /* compute the extensions and comments size */ + if (extensions) + ext_size = ExtensionsSize(info->extensions, info->nextensions); + if (cmts) + cmt_size = CommentsSize(info); + + /* write the header line */ + sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n"); + used_size = strlen(buf); + ptr_size = used_size + ext_size + cmt_size + 1; + ptr = (char *) XpmMalloc(ptr_size); + if (!ptr) + return XpmNoMemory; + strcpy(ptr, buf); + + /* write the values line */ + if (cmts && info->hints_cmt) { + sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt); + used_size += strlen(info->hints_cmt) + 5; + } + sprintf(buf, "\"%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); + l = strlen(buf); + + if (info && (info->valuemask & XpmHotspot)) { + sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot); + l = strlen(buf); + } + if (extensions) { + sprintf(buf + l, " XPMEXT"); + l = strlen(buf); + } + sprintf(buf + l, "\",\n"); + l = strlen(buf); + ptr_size += l; + p = (char *) XpmRealloc(ptr, ptr_size); + if (!p) + RETURN(XpmNoMemory); + ptr = p; + strcpy(ptr + used_size, buf); + used_size += l; + + /* write colors */ + if (cmts && info->colors_cmt) { + sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt); + used_size += strlen(info->colors_cmt) + 5; + } + ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size, + image->colorTable, image->ncolors, image->cpp); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * now we know the exact size we needed, realloc the data 4 = 1 (for + * '"') + 3 (for '",\n') 1 = - 2 is because the last line does not end + * with ',\n' + 3 (for '};\n') + */ + ptr_size += image->height * (image->width * image->cpp + 4) + 1; + + p = (char *) XpmRealloc(ptr, ptr_size); + if (!p) + RETURN(XpmNoMemory); + ptr = p; + + /* print pixels */ + if (cmts && info->pixels_cmt) { + sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt); + used_size += strlen(info->pixels_cmt) + 5; + } + WritePixels(ptr + used_size, &used_size, image->width, image->height, + image->cpp, image->data, image->colorTable); + + /* print extensions */ + if (extensions) + WriteExtensions(ptr + used_size, &used_size, + info->extensions, info->nextensions); + + /* close the array */ + sprintf(ptr + used_size, "};\n"); + + *buffer_return = ptr; + + return (XpmSuccess); +} + +static int +WriteColors(char **dataptr, unsigned int *data_size, unsigned int *used_size, + XpmColor *colors, unsigned int ncolors, unsigned int cpp) +{ + char buf[BUFSIZ]; + unsigned int a, key, l; + char *s, *s2; + char **defaults; + + *buf = '"'; + for (a = 0; a < ncolors; a++, colors++) { + + defaults = (char **) colors; + s = buf + 1; + strncpy(s, *defaults++, cpp); + s += cpp; + + for (key = 1; key <= NKEYS; key++, defaults++) { + if (s2 = *defaults) { + sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); + s += strlen(s); + } + } + strcpy(s, "\",\n"); + l = strlen(buf); + s = (char *) XpmRealloc(*dataptr, *data_size + l); + if (!s) + return (XpmNoMemory); + *data_size += l; + strcpy(s + *used_size, buf); + *used_size += l; + *dataptr = s; + } + return (XpmSuccess); +} + +static void +WritePixels(char *dataptr, unsigned int *used_size, unsigned int width, unsigned int height, + unsigned int cpp, unsigned int *pixels, XpmColor *colors) +{ + char *s = dataptr; + unsigned int x, y, h; + + h = height - 1; + for (y = 0; y < h; y++) { + *s++ = '"'; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + strcpy(s, "\",\n"); + s += 3; + } + /* duplicate some code to avoid a test in the loop */ + *s++ = '"'; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s++ = '"'; + *used_size += s - dataptr; +} + +static int +ExtensionsSize(XpmExtension *ext, unsigned int num) +{ + unsigned int x, y, a, size; + char **line; + + size = 0; + for (x = 0; x < num; x++, ext++) { + /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */ + size += strlen(ext->name) + 11; + a = ext->nlines; + for (y = 0, line = ext->lines; y < a; y++, line++) + /* 4 = 3 (for ',\n"') + 1 (for '"') */ + size += strlen(*line) + 4; + } + /* 13 is for ',\n"XPMENDEXT"' */ + return size + 13; +} + +static void +WriteExtensions(char *dataptr, unsigned int *used_size, XpmExtension *ext, unsigned int num) +{ + unsigned int x, y, a; + char **line; + char *s = dataptr; + + for (x = 0; x < num; x++, ext++) { + sprintf(s, ",\n\"XPMEXT %s\"", ext->name); + s += strlen(ext->name) + 11; + a = ext->nlines; + for (y = 0, line = ext->lines; y < a; y++, line++) { + sprintf(s, ",\n\"%s\"", *line); + s += strlen(*line) + 4; + } + } + strcpy(s, ",\n\"XPMENDEXT\""); + *used_size += s - dataptr + 13; +} + +static int +CommentsSize(XpmInfo *info) +{ + int size = 0; + + /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */ + if (info->hints_cmt) + size += 5 + strlen(info->hints_cmt); + + if (info->colors_cmt) + size += 5 + strlen(info->colors_cmt); + + if (info->pixels_cmt) + size += 5 + strlen(info->pixels_cmt); + + return size; +} diff --git a/src/xpm/crbuffrp.c b/src/xpm/crbuffrp.c new file mode 100644 index 0000000000..9a5b148b6b --- /dev/null +++ b/src/xpm/crbuffrp.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrBufFrP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM buffer * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifndef FOR_MSW + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include +#else +#include +#endif +#endif + +int +XpmCreateBufferFromPixmap(Display *display, char **buffer_return, Pixmap pixmap, Pixmap shapemask, + XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* create the buffer */ + ErrorStatus = XpmCreateBufferFromImage(display, buffer_return, ximage, + shapeimage, attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} +#endif diff --git a/src/xpm/crdatfri.c b/src/xpm/crdatfri.c new file mode 100644 index 0000000000..fe9b016e17 --- /dev/null +++ b/src/xpm/crdatfri.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrDataFI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include +#else +#include +#endif +#endif + +LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size, + XpmColor *colors, unsigned int ncolors, + unsigned int cpp)); + +LFUNC(CreatePixels, void, (char **dataptr, unsigned int width, + unsigned int height, unsigned int cpp, + unsigned int *pixels, XpmColor *colors)); + +LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num, + unsigned int *ext_size, + unsigned int *ext_nlines)); + +LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset, + XpmExtension *ext, unsigned int num, + unsigned int ext_nlines)); + +int +XpmCreateDataFromImage(Display *display, char ***data_return, XImage *image, + XImage *shapeimage, XpmAttributes *attributes) +{ + XpmImage xpmimage; + XpmInfo info; + int ErrorStatus; + + /* initialize return value */ + if (data_return) + *data_return = NULL; + + /* create an XpmImage from the image */ + ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage, + &xpmimage, attributes); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the data from the XpmImage */ + if (attributes) { + xpmSetInfo(&info, attributes); + ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info); + } else + ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL); + + /* free the XpmImage */ + XpmFreeXpmImage(&xpmimage); + + return (ErrorStatus); +} + +#undef RETURN +#define RETURN(status) \ +{ \ + if (header) { \ + for (l = 0; l < header_nlines; l++) \ + if (header[l]) \ + XpmFree(header[l]); \ + XpmFree(header); \ + } \ + return(status); \ +} + +int +XpmCreateDataFromXpmImage(char ***data_return, XpmImage *image, XpmInfo *info) +{ + /* calculation variables */ + int ErrorStatus; + char buf[BUFSIZ]; + char **header = NULL, **data, **sptr, **sptr2, *s; + unsigned int header_size, header_nlines; + unsigned int data_size, data_nlines; + unsigned int extensions = 0, ext_size = 0, ext_nlines = 0; + unsigned int offset, l, n; + + *data_return = NULL; + + extensions = info && (info->valuemask & XpmExtensions) + && info->nextensions; + + /* compute the number of extensions lines and size */ + if (extensions) + CountExtensions(info->extensions, info->nextensions, + &ext_size, &ext_nlines); + + /* + * alloc a temporary array of char pointer for the header section which + * is the hints line + the color table lines + */ + header_nlines = 1 + image->ncolors; + header_size = sizeof(char *) * header_nlines; + header = (char **) XpmCalloc(header_size, sizeof(char *)); + if (!header) + return (XpmNoMemory); + + /* print the hints line */ + s = buf; + sprintf(s, "%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); + s += strlen(s); + + if (info && (info->valuemask & XpmHotspot)) { + sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot); + s += strlen(s); + } + if (extensions) + sprintf(s, " XPMEXT"); + + l = strlen(buf) + 1; + *header = (char *) XpmMalloc(l); + if (!*header) + RETURN(XpmNoMemory); + header_size += l; + strcpy(*header, buf); + + /* print colors */ + ErrorStatus = CreateColors(header + 1, &header_size, + image->colorTable, image->ncolors, image->cpp); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* now we know the size needed, alloc the data and copy the header lines */ + offset = image->width * image->cpp + 1; + data_size = header_size + (image->height + ext_nlines) * sizeof(char *) + + image->height * offset + ext_size; + + data = (char **) XpmMalloc(data_size); + if (!data) + RETURN(XpmNoMemory); + + data_nlines = header_nlines + image->height + ext_nlines; + *data = (char *) (data + data_nlines); + n = image->ncolors; + for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) { + strcpy(*sptr, *sptr2); + *(sptr + 1) = *sptr + strlen(*sptr2) + 1; + } + + /* print pixels */ + data[header_nlines] = (char *) data + header_size + + (image->height + ext_nlines) * sizeof(char *); + + CreatePixels(data + header_nlines, image->width, image->height, + image->cpp, image->data, image->colorTable); + + /* print extensions */ + if (extensions) + CreateExtensions(data + header_nlines + image->height - 1, offset, + info->extensions, info->nextensions, + ext_nlines); + + *data_return = data; + + RETURN(XpmSuccess); +} + +static int +CreateColors(char **dataptr, unsigned int *data_size, XpmColor *colors, unsigned int ncolors, unsigned int cpp) +{ + char buf[BUFSIZ]; + unsigned int a, key, l; + char *s, *s2; + char **defaults; + + for (a = 0; a < ncolors; a++, colors++, dataptr++) { + + defaults = (char **) colors; + strncpy(buf, *defaults++, cpp); + s = buf + cpp; + + for (key = 1; key <= NKEYS; key++, defaults++) { + if (s2 = *defaults) { + sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); + s += strlen(s); + } + } + l = strlen(buf) + 1; + s = (char *) XpmMalloc(l); + if (!s) + return (XpmNoMemory); + *data_size += l; + strcpy(s, buf); + *dataptr = s; + } + return (XpmSuccess); +} + +static void +CreatePixels(char **dataptr, unsigned int width, unsigned int height, unsigned int cpp, + unsigned int *pixels, XpmColor *colors) +{ + char *s; + unsigned int x, y, h, offset; + + h = height - 1; + offset = width * cpp + 1; + for (y = 0; y < h; y++, dataptr++) { + s = *dataptr; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s = '\0'; + *(dataptr + 1) = *dataptr + offset; + } + /* duplicate some code to avoid a test in the loop */ + s = *dataptr; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s = '\0'; +} + +static void +CountExtensions(XpmExtension *ext, unsigned int num, unsigned int *ext_size, unsigned int *ext_nlines) +{ + unsigned int x, y, a, size, nlines; + char **line; + + size = 0; + nlines = 0; + for (x = 0; x < num; x++, ext++) { + /* 1 for the name */ + nlines += ext->nlines + 1; + /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */ + size += strlen(ext->name) + 8; + a = ext->nlines; + for (y = 0, line = ext->lines; y < a; y++, line++) + size += strlen(*line) + 1; + } + /* 10 and 1 are for the ending "XPMENDEXT" */ + *ext_size = size + 10; + *ext_nlines = nlines + 1; +} + +static void +CreateExtensions(char **dataptr, unsigned int offset, XpmExtension *ext, unsigned int num, unsigned int ext_nlines) +{ + unsigned int x, y, a, b; + char **line; + + *(dataptr + 1) = *dataptr + offset; + dataptr++; + a = 0; + for (x = 0; x < num; x++, ext++) { + sprintf(*dataptr, "XPMEXT %s", ext->name); + a++; + if (a < ext_nlines) + *(dataptr + 1) = *dataptr + strlen(ext->name) + 8; + dataptr++; + b = ext->nlines; + for (y = 0, line = ext->lines; y < b; y++, line++) { + strcpy(*dataptr, *line); + a++; + if (a < ext_nlines) + *(dataptr + 1) = *dataptr + strlen(*line) + 1; + dataptr++; + } + } + strcpy(*dataptr, "XPMENDEXT"); +} diff --git a/src/xpm/crdatfrp.c b/src/xpm/crdatfrp.c new file mode 100644 index 0000000000..63094d7155 --- /dev/null +++ b/src/xpm/crdatfrp.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrDataFP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifndef FOR_MSW + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include +#else +#include +#endif +#endif + +int +XpmCreateDataFromPixmap(Display *display, char ***data_return, Pixmap pixmap, + Pixmap shapemask, XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* create the data */ + ErrorStatus = XpmCreateDataFromImage(display, data_return, ximage, + shapeimage, attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} + +#endif diff --git a/src/xpm/create.c b/src/xpm/create.c new file mode 100644 index 0000000000..71d33caadb --- /dev/null +++ b/src/xpm/create.c @@ -0,0 +1,1461 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* create.c: * +* * +* XPM library * +* Create an X image and possibly its related shape mask * +* from the given xpmInternAttrib. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:ctype.h" +#else +#include +#endif + +LFUNC(xpmVisualType, int, (Visual *visual)); + +#ifndef FOR_MSW +LFUNC(SetCloseColor, int, (Display *display, Colormap colormap, + Visual *visual, XColor *col, + Pixel *image_pixel, Pixel *mask_pixel, + Pixel **pixels, unsigned int *npixels, + XpmAttributes *attributes, + XColor *cols, int ncols)); +#else +/* let the window system take care of close colors */ +#endif + +LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual, + char *colorname, unsigned int color_index, + Pixel *image_pixel, Pixel *mask_pixel, + unsigned int *mask_pixel_index, Pixel **pixels, + unsigned int *npixels, XpmAttributes *attributes, + XColor *cols, int ncols)); + +LFUNC(CreateXImage, int, (Display *display, Visual *visual, + unsigned int depth, unsigned int width, + unsigned int height, XImage **image_return)); + +LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes, + XpmColor *ct, unsigned int ncolors, Pixel *ip, + Pixel *mp, unsigned int *mask_pixel, + Pixel **pixels, unsigned int *npixels)); + +#ifndef FOR_MSW +/* XImage pixel routines */ +LFUNC(SetImagePixels, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(SetImagePixels32, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(SetImagePixels16, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(SetImagePixels8, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(SetImagePixels1, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); +#else /* ndef FOR_MSW */ +/* FOR_MSW pixel routine */ +LFUNC(MSWSetImagePixels, void, (Display *dc, XImage *image, + unsigned int width, unsigned int height, + unsigned int *pixelindex, Pixel *pixels)); +#endif /* ndef FOR_MSW */ + +#ifdef NEED_STRCASECMP +FUNC(strcasecmp, int, (char *s1, char *s2)); + +/* + * in case strcasecmp is not provided by the system here is one + * which does the trick + */ +int +strcasecmp(register char *s1, register char *s2) +{ + register int c1, c2; + + while (*s1 && *s2) { + c1 = tolower(*s1); + c2 = tolower(*s2); + if (c1 != c2) + return (c1 - c2); + s1++; + s2++; + } + return (int) (*s1 - *s2); +} + +#endif + +/* + * return the default color key related to the given visual + */ +static int +xpmVisualType(Visual *visual) +{ +#ifndef FOR_MSW +/* Xlib.h defines this to be c_class or class, depending + * on whether we're doing C++ or C + */ +#if defined(__cplusplus) || defined(c_plusplus) + switch (visual->c_class) +#else + switch (visual->class) +#endif + { + case StaticGray: + case GrayScale: + switch (visual->map_entries) { + case 2: + return (XPM_MONO); + case 4: + return (XPM_GRAY4); + default: + return (XPM_GRAY); + } + default: + return (XPM_COLOR); + } +#else + /* there should be a similar switch for MSW */ + return (XPM_COLOR); +#endif +} + + +typedef struct { + int cols_index; + long closeness; +} CloseColor; + +static int +closeness_cmp(const void *a, const void *b) +{ + CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b; + + /* cast to int as qsort requires */ + return (int) (x->closeness - y->closeness); +} + +#ifndef FOR_MSW +/* + * set a close color in case the exact one can't be set + * return 0 if success, 1 otherwise. + */ + +static int +SetCloseColor(Display *display, Colormap colormap, Visual *visual, XColor *col, + Pixel *image_pixel, Pixel *mask_pixel, Pixel **pixels, unsigned int *npixels, XpmAttributes *attributes, + XColor *cols, int ncols) +{ + + /* + * Allocation failed, so try close colors. To get here the visual must + * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor? + * What about sharing systems like QDSS?). Beware: we have to treat + * DirectColor differently. + */ + + + long int red_closeness, green_closeness, blue_closeness; + int n; + + if (attributes && (attributes->valuemask & XpmCloseness)) + red_closeness = green_closeness = blue_closeness = + attributes->closeness; + else { + red_closeness = attributes->red_closeness; + green_closeness = attributes->green_closeness; + blue_closeness = attributes->blue_closeness; + } + + + /* + * We sort the colormap by closeness and try to allocate the color + * closest to the target. If the allocation of this close color fails, + * which almost never happens, then one of two scenarios is possible. + * Either the colormap must have changed (since the last close color + * allocation or possibly while we were sorting the colormap), or the + * color is allocated as Read/Write by some other client. (Note: X + * _should_ allow clients to check if a particular color is Read/Write, + * but it doesn't! :-( ). We cannot determine which of these scenarios + * occurred, so we try the next closest color, and so on, until no more + * colors are within closeness of the target. If we knew that the + * colormap had changed, we could skip this sequence. + * + * If _none_ of the colors within closeness of the target can be allocated, + * then we can finally be pretty sure that the colormap has actually + * changed. In this case we try to allocate the original color (again), + * then try the closecolor stuff (again)... + * + * In theory it would be possible for an infinite loop to occur if another + * process kept changing the colormap every time we sorted it, so we set + * a maximum on the number of iterations. After this many tries, we use + * XGrabServer() to ensure that the colormap remains unchanged. + * + * This approach gives particularly bad worst case performance - as many as + * colormap reads and sorts may be needed, and as + * many as * attempted allocations + * may fail. On an 8-bit system, this means as many as 3 colormap reads, + * 3 sorts and 768 failed allocations per execution of this code! + * Luckily, my experiments show that in general use in a typical 8-bit + * color environment only about 1 in every 10000 allocations fails to + * succeed in the fastest possible time. So virtually every time what + * actually happens is a single sort followed by a successful allocate. + * The very first allocation also costs a colormap read, but no further + * reads are usually necessary. + */ + +#define ITERATIONS 2 /* more than one is almost never + * necessary */ + + for (n = 0; n <= ITERATIONS; ++n) { + CloseColor *closenesses = + (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor)); + int i, c; + + for (i = 0; i < ncols; ++i) { /* build & sort closenesses table */ +#define COLOR_FACTOR 3 +#define BRIGHTNESS_FACTOR 1 + + closenesses[i].cols_index = i; + closenesses[i].closeness = + COLOR_FACTOR * (abs((long) col->red - (long) cols[i].red) + + abs((long) col->green - (long) cols[i].green) + + abs((long) col->blue - (long) cols[i].blue)) + + BRIGHTNESS_FACTOR * abs(((long) col->red + + (long) col->green + + (long) col->blue) + - ((long) cols[i].red + + (long) cols[i].green + + (long) cols[i].blue)); + } + qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp); + + i = 0; + c = closenesses[i].cols_index; + while ((long) cols[c].red >= (long) col->red - red_closeness && + (long) cols[c].red <= (long) col->red + red_closeness && + (long) cols[c].green >= (long) col->green - green_closeness && + (long) cols[c].green <= (long) col->green + green_closeness && + (long) cols[c].blue >= (long) col->blue - blue_closeness && + (long) cols[c].blue <= (long) col->blue + blue_closeness) { + if (XAllocColor(display, colormap, &cols[c])) { + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + *image_pixel = cols[c].pixel; + *mask_pixel = 1; + (*pixels)[*npixels] = cols[c].pixel; + (*npixels)++; + return (0); + } else { + ++i; + if (i == ncols) + break; + c = closenesses[i].cols_index; + } + } + + /* Couldn't allocate _any_ of the close colors! */ + + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + + if (i == 0 || i == ncols) /* no color close enough or cannot */ + return (1); /* alloc any color (full of r/w's) */ + + if (XAllocColor(display, colormap, col)) { + *image_pixel = col->pixel; + *mask_pixel = 1; + (*pixels)[*npixels] = col->pixel; + (*npixels)++; + return (0); + } else { /* colormap has probably changed, so + * re-read... */ + if (n == ITERATIONS - 1) + XGrabServer(display); + +#if 0 + if (visual->c_class == DirectColor) { + /* TODO */ + } else +#endif + XQueryColors(display, colormap, cols, ncols); + } + } + return (1); +} + +#define USE_CLOSECOLOR attributes && \ +(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \ + || ((attributes->valuemask & XpmRGBCloseness) && \ + attributes->red_closeness != 0 \ + && attributes->green_closeness != 0 \ + && attributes->blue_closeness != 0)) + +#else + /* FOR_MSW part */ + /* nothing to do here, the window system does it */ +#endif + +/* + * set the color pixel related to the given colorname, + * return 0 if success, 1 otherwise. + */ + +static int +SetColor(Display *display, Colormap colormap, Visual *visual, char *colorname, unsigned int color_index, + Pixel *image_pixel, Pixel *mask_pixel, unsigned int *mask_pixel_index, + Pixel **pixels, unsigned int *npixels, XpmAttributes *attributes, XColor *cols, int ncols) +{ + XColor xcolor; + + if (strcasecmp(colorname, TRANSPARENT_COLOR)) { +#ifdef wx_msw + if (!XParseColor(display, (Colormap *)colormap, colorname, &xcolor)) +#else + if (!XParseColor(display, (Colormap)colormap, colorname, &xcolor)) +#endif + return (1); +#ifdef wx_msw + if (!XAllocColor(display, (Colormap *)colormap, &xcolor)) { +#else + if (!XAllocColor(display, (Colormap)colormap, &xcolor)) { +#endif +#ifndef FOR_MSW + if (USE_CLOSECOLOR) + return (SetCloseColor(display, colormap, visual, &xcolor, + image_pixel, mask_pixel, pixels, npixels, + attributes, cols, ncols)); + else +#endif /* ndef FOR_MSW */ + return (1); + } + *image_pixel = xcolor.pixel; + *mask_pixel = 1; + (*pixels)[*npixels] = xcolor.pixel; + (*npixels)++; + } else { + *image_pixel = 0; + *mask_pixel = 0; + *mask_pixel_index = color_index; /* store the color table index */ + } + return (0); +} + + +static int +CreateColors(Display *display, XpmAttributes *attributes, XpmColor *ct, unsigned int ncolors, + Pixel *ip, Pixel *mp, unsigned int *mask_pixel, Pixel **pixels, unsigned int *npixels) +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + XpmColorSymbol *colorsymbols; + unsigned int numsymbols; + + char *colorname; + unsigned int a, b, l; + int pixel_defined; + unsigned int key; + XpmColorSymbol *symbol; + char **defaults; + int ErrorStatus = XpmSuccess; + char *s; + int default_index; + + XColor *cols = NULL; + unsigned int ncols = 0; + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && attributes->valuemask & XpmColorSymbols) { + colorsymbols = attributes->colorsymbols; + numsymbols = attributes->numsymbols; + } else + numsymbols = 0; + + if (attributes && attributes->valuemask & XpmVisual) + visual = attributes->visual; + else + visual = XDefaultVisual(display, XDefaultScreen(display)); + + if (attributes && attributes->valuemask & XpmColormap) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + + if (attributes && attributes->valuemask & XpmColorKey) + key = attributes->color_key; + else + key = xpmVisualType(visual); + +#ifndef FOR_MSW + if (USE_CLOSECOLOR) { + /* originally from SetCloseColor */ +#if 0 + if (visual->c_class == DirectColor) { + + /* + * TODO: Implement close colors for DirectColor visuals. This is + * difficult situation. Chances are that we will never get here, + * because any machine that supports DirectColor will probably + * also support TrueColor (and probably PseudoColor). Also, + * DirectColor colormaps can be very large, so looking for close + * colors may be too slow. + */ + } else { +#endif + int i; + + ncols = visual->map_entries; + cols = (XColor *) XpmCalloc(ncols, sizeof(XColor)); + for (i = 0; i < ncols; ++i) + cols[i].pixel = i; + XQueryColors(display, colormap, cols, ncols); +#if 0 + } +#endif + } +#endif /* ndef FOR_MSW */ + + switch (key) { + case XPM_MONO: + default_index = 2; + break; + case XPM_GRAY4: + default_index = 3; + break; + case XPM_GRAY: + default_index = 4; + break; + case XPM_COLOR: + default: + default_index = 5; + break; + } + + for (a = 0; a < ncolors; a++, ct++, ip++, mp++) { + colorname = NULL; + pixel_defined = False; + defaults = (char **) ct; + + /* + * look for a defined symbol + */ + if (numsymbols) { + s = defaults[1]; + for (l = 0, symbol = colorsymbols; l < numsymbols; l++, symbol++) { + if (symbol->name && s && !strcmp(symbol->name, s)) + /* override name */ + break; + if (!symbol->name && symbol->value) { /* override value */ + int def_index = default_index; + + while (defaults[def_index] == NULL) /* find defined + * colorname */ + --def_index; + if (def_index < 2) {/* nothing towards mono, so try + * towards color */ + def_index = default_index + 1; + while (def_index <= 5 && defaults[def_index] == NULL) + ++def_index; + } + if (def_index >= 2 && defaults[def_index] != NULL && + !strcasecmp(symbol->value, defaults[def_index])) + break; + } + } + if (l != numsymbols) { + if (symbol->name && symbol->value) + colorname = symbol->value; + else + pixel_defined = True; + } + } + if (!pixel_defined) { /* pixel not given as symbol value */ + if (colorname) { /* colorname given as symbol value */ + if (!SetColor(display, colormap, visual, colorname, a, ip, mp, + mask_pixel, pixels, npixels, attributes, + cols, ncols)) + pixel_defined = True; + else + ErrorStatus = XpmColorError; + } + b = key; + while (!pixel_defined && b > 1) { + if (defaults[b]) { + if (!SetColor(display, colormap, visual, defaults[b], + a, ip, mp, mask_pixel, pixels, npixels, + attributes, cols, ncols)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + b--; + } + b = key + 1; + while (!pixel_defined && b < NKEYS + 1) { + if (defaults[b]) { + if (!SetColor(display, colormap, visual, defaults[b], + a, ip, mp, mask_pixel, pixels, npixels, + attributes, cols, ncols)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + b++; + } + if (!pixel_defined) { + if (cols) + XpmFree(cols); + return (XpmColorFailed); + } + } else { + *ip = colorsymbols[l].pixel; + if (symbol->value + && !strcasecmp(symbol->value, TRANSPARENT_COLOR)) { + *mp = 0; + *mask_pixel = 0; + } else + *mp = 1; + } + } + if (cols) + XpmFree(cols); + return (ErrorStatus); +} + + +/* function call in case of error, frees only locally allocated variables */ +#undef RETURN +#define RETURN(status) \ +{ \ + if (ximage) XDestroyImage(ximage); \ + if (shapeimage) XDestroyImage(shapeimage); \ + if (ximage_pixels) XpmFree(ximage_pixels); \ + if (mask_pixels) XpmFree(mask_pixels); \ + if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \ + if (pixels) XpmFree(pixels); \ + return (status); \ +} + +int +XpmCreateImageFromXpmImage(Display *display, XpmImage *image, + XImage **image_return, XImage **shapeimage_return, XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + unsigned int depth; + + /* variables to return */ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int mask_pixel; + int ErrorStatus; + + /* calculation variables */ + Pixel *ximage_pixels = NULL; + Pixel *mask_pixels = NULL; + Pixel *pixels = NULL; /* allocated pixels */ + unsigned int npixels = 0; /* number of allocated pixels */ + + /* initialize return values */ + if (image_return) + *image_return = NULL; + if (shapeimage_return) + *shapeimage_return = NULL; + + /* retrieve information from the XpmAttributes */ + if (attributes && (attributes->valuemask & XpmVisual)) + visual = attributes->visual; + else + visual = XDefaultVisual(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmColormap)) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmDepth)) + depth = attributes->depth; + else + depth = XDefaultDepth(display, XDefaultScreen(display)); + + ErrorStatus = XpmSuccess; + + /* malloc pixels index tables */ + ximage_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!ximage_pixels) + return (XpmNoMemory); + + mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!mask_pixels) + RETURN(XpmNoMemory); + + mask_pixel = XpmUndefPixel; + + /* maximum of allocated pixels will be the number of colors */ + pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!pixels) + RETURN(XpmNoMemory); + + /* get pixel colors, store them in index tables */ + ErrorStatus = CreateColors(display, attributes, image->colorTable, + image->ncolors, ximage_pixels, mask_pixels, + &mask_pixel, &pixels, &npixels); + + if (ErrorStatus != XpmSuccess + && (ErrorStatus < 0 || (attributes + && (attributes->valuemask & XpmExactColors) + && attributes->exactColors))) + RETURN(ErrorStatus); + + /* create the ximage */ + if (image_return) { + ErrorStatus = CreateXImage(display, visual, depth, + image->width, image->height, &ximage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#ifndef FOR_MSW + + /* + * set the ximage data + * + * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use + * optimized functions, otherwise use slower but sure general one. + * + */ + + if (ximage->depth == 1) + SetImagePixels1(ximage, image->width, image->height, + image->data, ximage_pixels); + else if (ximage->bits_per_pixel == 8) + SetImagePixels8(ximage, image->width, image->height, + image->data, ximage_pixels); + else if (ximage->bits_per_pixel == 16) + SetImagePixels16(ximage, image->width, image->height, + image->data, ximage_pixels); + else if (ximage->bits_per_pixel == 32) + SetImagePixels32(ximage, image->width, image->height, + image->data, ximage_pixels); + else + SetImagePixels(ximage, image->width, image->height, + image->data, ximage_pixels); +#else /* FOR_MSW */ + MSWSetImagePixels(display, ximage, image->width, image->height, + image->data, ximage_pixels); +#endif + } + /* create the shape mask image */ + if (mask_pixel != XpmUndefPixel && shapeimage_return) { + ErrorStatus = CreateXImage(display, visual, 1, image->width, + image->height, &shapeimage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#ifndef FOR_MSW + SetImagePixels1(shapeimage, image->width, image->height, + image->data, mask_pixels); +#else + MSWSetImagePixels(display, shapeimage, image->width, image->height, + image->data, mask_pixels); +#endif + + } + XpmFree(mask_pixels); + XpmFree(pixels); + + /* if requested store alloc'ed pixels in the XpmAttributes structure */ + if (attributes) { + if (attributes->valuemask & XpmReturnPixels || +/* 3.2 backward compatibility code */ + attributes->valuemask & XpmReturnInfos) { +/* end 3.2 bc */ + if (mask_pixel != XpmUndefPixel) { + Pixel *pixels, *p1, *p2; + unsigned int a; + + attributes->npixels = image->ncolors - 1; + pixels = (Pixel *) XpmMalloc(sizeof(Pixel) + * attributes->npixels); + if (pixels) { + p1 = ximage_pixels; + p2 = pixels; + for (a = 0; a < image->ncolors; a++, p1++) + if (a != mask_pixel) + *p2++ = *p1; + attributes->pixels = pixels; + } else { + /* if error just say we can't return requested data */ + attributes->valuemask &= ~XpmReturnPixels; +/* 3.2 backward compatibility code */ + attributes->valuemask &= ~XpmReturnInfos; +/* end 3.2 bc */ + attributes->pixels = NULL; + attributes->npixels = 0; + } + XpmFree(ximage_pixels); + } else { + attributes->pixels = ximage_pixels; + attributes->npixels = image->ncolors; + } + attributes->mask_pixel = mask_pixel; + } else + XpmFree(ximage_pixels); + } else + XpmFree(ximage_pixels); + + /* return created images */ + if (image_return) + *image_return = ximage; + if (shapeimage_return) + *shapeimage_return = shapeimage; + + return (ErrorStatus); +} + + +/* + * Create an XImage + */ +static int +CreateXImage(Display *display, Visual *visual, unsigned int depth, + unsigned int width, unsigned int height, XImage **image_return) +{ + int bitmap_pad; + + /* first get bitmap_pad */ + if (depth > 16) + bitmap_pad = 32; + else if (depth > 8) + bitmap_pad = 16; + else + bitmap_pad = 8; + + /* then create the XImage with data = NULL and bytes_per_line = 0 */ + *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0, + width, height, bitmap_pad, 0); + if (!*image_return) + return (XpmNoMemory); + +#ifndef FOR_MSW + /* now that bytes_per_line must have been set properly alloc data */ + (*image_return)->data = + (char *) XpmMalloc((*image_return)->bytes_per_line * height); + + if (!(*image_return)->data) { + XDestroyImage(*image_return); + *image_return = NULL; + return (XpmNoMemory); + } +#else + /* under FOR_MSW XCreateImage has done it all */ +#endif + return (XpmSuccess); +} + +#ifndef FOR_MSW +/* + * The functions below are written from X11R5 MIT's code (XImUtil.c) + * + * The idea is to have faster functions than the standard XPutPixel function + * to build the image data. Indeed we can speed up things by suppressing tests + * performed for each pixel. We do the same tests but at the image level. + * We also assume that we use only ZPixmap images with null offsets. + */ + +LFUNC(_putbits, void, (register char *src, int dstoffset, + register int numbits, register char *dst)); + +LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb)); + +static unsigned char Const _reverse_byte[0x100] = { + 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 int +_XReverse_Bytes(register unsigned char *bpt, register int nb) +{ + do { + *bpt = _reverse_byte[*bpt]; + bpt++; + } while (--nb > 0); + return 0; +} + + +void +xpm_xynormalizeimagebits(register unsigned char *bp, register XImage *img) +{ + register unsigned char c; + + if (img->byte_order != img->bitmap_bit_order) { + switch (img->bitmap_unit) { + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } + } + if (img->bitmap_bit_order == MSBFirst) + _XReverse_Bytes(bp, img->bitmap_unit >> 3); +} + +void +xpm_znormalizeimagebits(register unsigned char *bp, register XImage *img) +{ + register unsigned char c; + + switch (img->bits_per_pixel) { + + case 2: + _XReverse_Bytes(bp, 1); + break; + + case 4: + *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); + break; + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 24: + c = *(bp + 2); + *(bp + 2) = *bp; + *bp = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } +} + +static unsigned char Const _lomask[0x09] = { +0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; +static unsigned char Const _himask[0x09] = { +0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; + +static void +_putbits(register char *src, int dstoffset, register int numbits, register char *dst) + +/* register char *src; */ /* address of source bit string */ +/* int dstoffset; */ /* bit offset into destination; + * range is 0-31 */ +/* register int numbits; */ /* number of bits to copy to + * destination */ +/* register char *dst; */ /* address of destination bit string */ +{ + register unsigned char chlo, chhi; + int hibits; + + dst = dst + (dstoffset >> 3); + dstoffset = dstoffset & 7; + hibits = 8 - dstoffset; + chlo = *dst & _lomask[dstoffset]; + for (;;) { + chhi = (*src << dstoffset) & _himask[dstoffset]; + if (numbits <= hibits) { + chhi = chhi & _lomask[dstoffset + numbits]; + *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; + break; + } + *dst = chhi | chlo; + dst++; + numbits = numbits - hibits; + chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; + src++; + if (numbits <= dstoffset) { + chlo = chlo & _lomask[numbits]; + *dst = (*dst & _himask[numbits]) | chlo; + break; + } + numbits = numbits - dstoffset; + } +} + +/* + * Default method to write pixels into a Z image data structure. + * The algorithm used is: + * + * copy the destination bitmap_unit or Zpixel to temp + * normalize temp if needed + * copy the pixel bits into the temp + * renormalize temp if needed + * copy the temp back into the destination image data + */ + +static void +SetImagePixels(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels) +{ + register char *src; + register char *dst; + register unsigned int *iptr; + register int x, y, i; + register char *data; + Pixel pixel, px; + int nbytes, depth, ibu, ibpp; + + data = image->data; + iptr = pixelindex; + depth = image->depth; + if (depth == 1) { + ibu = image->bitmap_unit; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = pixels[*iptr]; + for (i = 0, px = pixel; i < sizeof(unsigned long); + i++, px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &data[XYINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + nbytes = ibu >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + XYNORMALIZE(&px, image); + _putbits((char *) &pixel, (x % ibu), 1, (char *) &px); + XYNORMALIZE(&px, image); + src = (char *) &px; + dst = &data[XYINDEX(x, y, image)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + } + } else { + ibpp = image->bits_per_pixel; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = pixels[*iptr]; + if (depth == 4) + pixel &= 0xf; + for (i = 0, px = pixel; i < sizeof(unsigned long); i++, + px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &data[ZINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + nbytes = (ibpp + 7) >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, image); + _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); + ZNORMALIZE(&px, image); + src = (char *) &px; + dst = &data[ZINDEX(x, y, image)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + } + } +} + +/* + * write pixels into a 32-bits Z image data structure + */ + +#ifndef WORD64 +/* this item is static but deterministic so let it slide; doesn't + * hurt re-entrancy of this library. Note if it is actually const then would + * be OK under rules of ANSI-C but probably not C++ which may not + * want to allocate space for it. + */ +static unsigned long /* constant */ RTXpm_byteorderpixel = MSBFirst << 24; + +#endif + +/* + WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original + 3.2e code - by default you get the speeded-up version. +*/ + +static void +SetImagePixels32(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels) +{ + unsigned char *data; + unsigned int *iptr; + int y; + Pixel pixel; + +#ifdef WITHOUT_SPEEDUPS + + int x; + unsigned char *addr; + + data = (unsigned char *) image->data; + iptr = pixelindex; +#ifndef WORD64 + if (*((char *) &RTXpm_byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + *((unsigned long *) addr) = pixels[*iptr]; + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = pixels[*iptr]; + addr[0] = pixel >> 24; + addr[1] = pixel >> 16; + addr[2] = pixel >> 8; + addr[3] = pixel; + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = pixels[*iptr]; + addr[0] = pixel; + addr[1] = pixel >> 8; + addr[2] = pixel >> 16; + addr[3] = pixel >> 24; + } + +#else /* WITHOUT_SPEEDUPS */ + + int bpl = image->bytes_per_line; + unsigned char *data_ptr, *max_data; + + data = (unsigned char *) image->data; + iptr = pixelindex; +#ifndef WORD64 + if (*((char *) &RTXpm_byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 2); + + while (data_ptr < max_data) { + *((unsigned long *) data_ptr) = pixels[*(iptr++)]; + data_ptr += (1 << 2); + } + data += bpl; + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 2); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + *data_ptr++ = pixel >> 24; + *data_ptr++ = pixel >> 16; + *data_ptr++ = pixel >> 8; + *data_ptr++ = pixel; + + } + data += bpl; + } + else + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 2); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + *data_ptr++ = pixel; + *data_ptr++ = pixel >> 8; + *data_ptr++ = pixel >> 16; + *data_ptr++ = pixel >> 24; + } + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ +} + +/* + * write pixels into a 16-bits Z image data structure + */ + +static void +SetImagePixels16(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels) +{ + unsigned char *data; + unsigned int *iptr; + int y; + +#ifdef WITHOUT_SPEEDUPS + + int x; + unsigned char *addr; + + data = (unsigned char *) image->data; + iptr = pixelindex; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + addr[0] = pixels[*iptr] >> 8; + addr[1] = pixels[*iptr]; + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + addr[0] = pixels[*iptr]; + addr[1] = pixels[*iptr] >> 8; + } + +#else /* WITHOUT_SPEEDUPS */ + + Pixel pixel; + + int bpl = image->bytes_per_line; + unsigned char *data_ptr, *max_data; + + data = (unsigned char *) image->data; + iptr = pixelindex; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 1); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + data_ptr[0] = pixel >> 8; + data_ptr[1] = pixel; + + data_ptr += (1 << 1); + } + data += bpl; + } + else + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 1); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + data_ptr[0] = pixel; + data_ptr[1] = pixel >> 8; + + data_ptr += (1 << 1); + } + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ +} + +/* + * write pixels into a 8-bits Z image data structure + */ + +static void +SetImagePixels8(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels) +{ + char *data; + unsigned int *iptr; + int y; + +#ifdef WITHOUT_SPEEDUPS + + int x; + + data = image->data; + iptr = pixelindex; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) + data[ZINDEX8(x, y, image)] = pixels[*iptr]; + +#else /* WITHOUT_SPEEDUPS */ + + int bpl = image->bytes_per_line; + char *data_ptr, *max_data; + + data = image->data; + iptr = pixelindex; + + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + width; + + while (data_ptr < max_data) + *(data_ptr++) = pixels[*(iptr++)]; + + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ +} + +/* + * write pixels into a 1-bit depth image data structure and **offset null** + */ + +static void +SetImagePixels1(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels) +{ + if (image->byte_order != image->bitmap_bit_order) + SetImagePixels(image, width, height, pixelindex, pixels); + else { + unsigned int *iptr; + int y; + char *data; + +#ifdef WITHOUT_SPEEDUPS + + int x; + + data = image->data; + iptr = pixelindex; + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + if (pixels[*iptr] & 1) + data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7); + else + data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7)); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + if (pixels[*iptr] & 1) + data[ZINDEX1(x, y, image)] |= 1 << (x & 7); + else + data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7)); + } + +#else /* WITHOUT_SPEEDUPS */ + + char value; + char *data_ptr, *max_data; + int bpl = image->bytes_per_line; + int diff, count; + + data = image->data; + iptr = pixelindex; + + diff = width & 7; + width >>= 3; + + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + width; + while (data_ptr < max_data) { + value = 0; + + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + + *(data_ptr++) = value; + } + if (diff) { + value = 0; + for (count = 0; count < diff; count++) { + if (pixels[*(iptr++)] & 1) + value |= (0x80 >> count); + } + *(data_ptr) = value; + } + data += bpl; + } + else + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + width; + while (data_ptr < max_data) { + value = 0; + iptr += 8; + + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + + iptr += 8; + *(data_ptr++) = value; + } + if (diff) { + value = 0; + for (count = 0; count < diff; count++) { + if (pixels[*(iptr++)] & 1) + value |= (1 << count); + } + *(data_ptr) = value; + } + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ + } +} + +int +XpmCreatePixmapFromXpmImage(Display *display, Drawable d, XpmImage *image, + Pixmap *pixmap_return, Pixmap *shapemask_return, XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the ximages */ + ErrorStatus = XpmCreateImageFromXpmImage(display, image, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? + &shapeimage : NULL), + attributes); + if (ErrorStatus < 0) + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} + +#else /* FOR_MSW part follows */ +static void +MSWSetImagePixels(Display *dc, XImage *image, unsigned int width, unsigned int height, + unsigned int *pixelindex, Pixel *pixels) +{ + unsigned int *data = pixelindex; + unsigned int x, y; + + SelectObject(*dc, image->bitmap); + if (image->depth == 1) + { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + SetPixel(*dc, x, y, (pixels[*(data++)] ? RGB(255,255,255) : 0)); /* data is [x+y*width] */ + } + } + } + else + { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */ + } + } + } +} + +#endif /* FOR_MSW */ diff --git a/src/xpm/crifrbuf.c b/src/xpm/crifrbuf.c new file mode 100644 index 0000000000..62827b8200 --- /dev/null +++ b/src/xpm/crifrbuf.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrIFrBuf.c: * +* * +* XPM library * +* Parse an Xpm buffer (file in memory) and create the image and possibly its * +* mask * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" + +int +XpmCreateImageFromBuffer(Display *display, char *buffer, XImage **image_return, + XImage **shapeimage_return, XpmAttributes *attributes) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + /* create an XpmImage from the buffer */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = XpmCreateXpmImageFromBuffer(buffer, &image, &info); + } else + ErrorStatus = XpmCreateXpmImageFromBuffer(buffer, &image, NULL); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the related ximages */ + ErrorStatus = XpmCreateImageFromXpmImage(display, &image, + image_return, shapeimage_return, + attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmCreateXpmImageFromBuffer(char *buffer, XpmImage *image, XpmInfo *info) +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open buffer to read */ + xpmOpenBuffer(buffer, &mdata); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/crifrdat.c b/src/xpm/crifrdat.c new file mode 100644 index 0000000000..74fa2658c6 --- /dev/null +++ b/src/xpm/crifrdat.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrIFrData.c: * +* * +* XPM library * +* Parse an Xpm array and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" + +int +XpmCreateImageFromData(Display *display, char **data, XImage **image_return, + XImage **shapeimage_return, XpmAttributes *attributes) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + /* create an XpmImage from the file */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = XpmCreateXpmImageFromData(data, &image, &info); + } else + ErrorStatus = XpmCreateXpmImageFromData(data, &image, NULL); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the related ximages */ + ErrorStatus = XpmCreateImageFromXpmImage(display, &image, + image_return, shapeimage_return, + attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmCreateXpmImageFromData(char **data, XpmImage *image, XpmInfo *info) +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open data */ + xpmOpenArray(data, &mdata); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/crpfrbuf.c b/src/xpm/crpfrbuf.c new file mode 100644 index 0000000000..e6cd21cf42 --- /dev/null +++ b/src/xpm/crpfrbuf.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrPFrBuf.c: * +* * +* XPM library * +* Parse an Xpm buffer and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifndef FOR_MSW +#include "xpm34p.h" + +int +XpmCreatePixmapFromBuffer(Display *display, Drawable d, char *buffer, Pixmap *pixmap_return, + Pixmap *shapemask_return, XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the images */ + ErrorStatus = XpmCreateImageFromBuffer(display, buffer, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? + &shapeimage : NULL), + attributes); + + if (ErrorStatus < 0) /* fatal error */ + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} +#endif diff --git a/src/xpm/crpfrdat.c b/src/xpm/crpfrdat.c new file mode 100644 index 0000000000..7d0cf6aa16 --- /dev/null +++ b/src/xpm/crpfrdat.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmCrPFrData.c: * +* * +* XPM library * +* Parse an Xpm array and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" + +#ifndef FOR_MSW +int +XpmCreatePixmapFromData(Display *display, Drawable d, char **data, Pixmap *pixmap_return, + Pixmap *shapemask_return, XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the images */ + ErrorStatus = XpmCreateImageFromData(display, data, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? + &shapeimage : NULL), + attributes); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + if (ErrorStatus < 0) /* fatal error */ + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} +#endif diff --git a/src/xpm/data.c b/src/xpm/data.c new file mode 100644 index 0000000000..247f8aaa09 --- /dev/null +++ b/src/xpm/data.c @@ -0,0 +1,627 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* data.c: * +* * +* XPM library * +* IO utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* Official version number */ +static char *RCS_Version = "$XpmVersion: 3.4b $"; + +/* Internal version number */ +static char *RCS_Id = "$Id$"; + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:stat.h" +#include "sys$library:ctype.h" +#else +#include +#include +#include +#endif + +#include + +LFUNC(ParseComment, int, (xpmData * mdata)); + +static int +ParseComment(xpmData *mdata) +{ + if (mdata->type == XPMBUFFER) { + register char c; + register unsigned int n = 0; + unsigned int notend; + char *s, *s2; + + s = mdata->Comment; + *s = mdata->Bcmt[0]; + + /* skip the string beginning comment */ + s2 = mdata->Bcmt; + do { + c = *mdata->cptr++; + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c && c != mdata->Bos); + + if (*s2 != '\0') { + /* this wasn't the beginning of a comment */ + mdata->cptr -= n; + return 0; + } + /* store comment */ + mdata->Comment[0] = *s; + s = mdata->Comment; + notend = 1; + n = 0; + while (notend) { + s2 = mdata->Ecmt; + while (*s != *s2 && c && c != mdata->Bos) { + c = *mdata->cptr++; + *++s = c; + n++; + } + mdata->CommentLength = n; + do { + c = *mdata->cptr++; + n++; + *++s = c; + s2++; + } while (c == *s2 && *s2 != '\0' && c && c != mdata->Bos); + if (*s2 == '\0') { + /* this is the end of the comment */ + notend = 0; + mdata->cptr--; + } + } + return 0; + } else { + FILE *file = mdata->stream.file; + register int c; + register unsigned int n = 0, a; + unsigned int notend; + char *s, *s2; + + s = mdata->Comment; + *s = mdata->Bcmt[0]; + + /* skip the string beginning comment */ + s2 = mdata->Bcmt; + do { + c = getc(file); + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' + && c != EOF && c != mdata->Bos); + + if (*s2 != '\0') { + /* this wasn't the beginning of a comment */ + /* put characters back in the order that we got them */ + for (a = n; a > 0; a--, s--) + ungetc(*s, file); + return 0; + } + /* store comment */ + mdata->Comment[0] = *s; + s = mdata->Comment; + notend = 1; + n = 0; + while (notend) { + s2 = mdata->Ecmt; + while (*s != *s2 && c != EOF && c != mdata->Bos) { + c = getc(file); + *++s = c; + n++; + } + mdata->CommentLength = n; + do { + c = getc(file); + n++; + *++s = c; + s2++; + } while (c == *s2 && *s2 != '\0' + && c != EOF && c != mdata->Bos); + if (*s2 == '\0') { + /* this is the end of the comment */ + notend = 0; + ungetc(*s, file); + } + } + return 0; + } +} + +/* + * skip to the end of the current string and the beginning of the next one + */ +int +xpmNextString(xpmData *mdata) +{ + if (!mdata->type) + mdata->cptr = (mdata->stream.data)[++mdata->line]; + else if (mdata->type == XPMBUFFER) { + register char c; + + /* get to the end of the current string */ + if (mdata->Eos) + while ((c = *mdata->cptr++) && c != mdata->Eos); + + /* + * then get to the beginning of the next string looking for possible + * comment + */ + if (mdata->Bos) { + while ((c = *mdata->cptr++) && c != mdata->Bos) + if (mdata->Bcmt && c == mdata->Bcmt[0]) + ParseComment(mdata); + } else if (mdata->Bcmt) { /* XPM2 natural */ + while ((c = *mdata->cptr++) == mdata->Bcmt[0]) + ParseComment(mdata); + mdata->cptr--; + } + } else { + register int c; + FILE *file = mdata->stream.file; + + /* get to the end of the current string */ + if (mdata->Eos) + while ((c = getc(file)) != mdata->Eos && c != EOF); + + /* + * then get to the beginning of the next string looking for possible + * comment + */ + if (mdata->Bos) { + while ((c = getc(file)) != mdata->Bos && c != EOF) + if (mdata->Bcmt && c == mdata->Bcmt[0]) + ParseComment(mdata); + + } else if (mdata->Bcmt) { /* XPM2 natural */ + while ((c = getc(file)) == mdata->Bcmt[0]) + ParseComment(mdata); + ungetc(c, file); + } + } + return 0; +} + + +/* + * skip whitespace and compute the following unsigned int, + * returns 1 if one is found and 0 if not + */ +int +xpmNextUI(xpmData *mdata, unsigned int *ui_return) +{ + char buf[BUFSIZ]; + int l; + + l = xpmNextWord(mdata, buf, BUFSIZ); + return atoui(buf, l, ui_return); +} + +/* + * skip whitespace and return the following word + */ +unsigned int +xpmNextWord(xpmData *mdata, char *buf, unsigned int buflen) +{ + register unsigned int n = 0; + int c; + + if (!mdata->type || mdata->type == XPMBUFFER) { + while (isspace(c = *mdata->cptr) && c != mdata->Eos) + mdata->cptr++; + do { + c = *mdata->cptr++; + *buf++ = c; + n++; + } while (!isspace(c) && c != mdata->Eos && n < buflen); + n--; + mdata->cptr--; + } else { + FILE *file = mdata->stream.file; + + while ((c = getc(file)) != EOF && isspace(c) && c != mdata->Eos); + while (!isspace(c) && c != mdata->Eos && c != EOF && n < buflen) { + *buf++ = c; + n++; + c = getc(file); + } + ungetc(c, file); + } + return (n); +} + +/* + * return end of string - WARNING: malloc! + */ +int +xpmGetString(xpmData *mdata, char **sptr, unsigned int *l) +{ + unsigned int i, n = 0; + int c; + char *p, *q, buf[BUFSIZ]; + + if (!mdata->type || mdata->type == XPMBUFFER) { + if (mdata->cptr) { + char *start; + + while (isspace(c = *mdata->cptr) && c != mdata->Eos) + mdata->cptr++; + start = mdata->cptr; + while ((c = *mdata->cptr) && c != mdata->Eos) + mdata->cptr++; + n = mdata->cptr - start + 1; + p = (char *) XpmMalloc(n); + if (!p) + return (XpmNoMemory); + strncpy(p, start, n); + if (mdata->type) /* XPMBUFFER */ + p[n - 1] = '\0'; + } + } else { + FILE *file = mdata->stream.file; + + while ((c = getc(file)) != EOF && isspace(c) && c != mdata->Eos); + if (c == EOF) + return (XpmFileInvalid); + p = NULL; + i = 0; + q = buf; + p = (char *) XpmMalloc(1); + while (c != mdata->Eos && c != EOF) { + if (i == BUFSIZ) { + /* get to the end of the buffer */ + /* malloc needed memory */ + q = (char *) XpmRealloc(p, n + i); + if (!q) { + XpmFree(p); + return (XpmNoMemory); + } + p = q; + q += n; + /* and copy what we already have */ + strncpy(q, buf, i); + n += i; + i = 0; + q = buf; + } + *q++ = c; + i++; + c = getc(file); + } + if (c == EOF) { + XpmFree(p); + return (XpmFileInvalid); + } + if (n + i != 0) { + /* malloc needed memory */ + q = (char *) XpmRealloc(p, n + i + 1); + if (!q) { + XpmFree(p); + return (XpmNoMemory); + } + p = q; + q += n; + /* and copy the buffer */ + strncpy(q, buf, i); + n += i; + p[n++] = '\0'; + } else { + *p = '\0'; + n = 1; + } + ungetc(c, file); + } + *sptr = p; + *l = n; + return (XpmSuccess); +} + +/* + * get the current comment line + */ +int +xpmGetCmt(xpmData *mdata, char **cmt) +{ + if (!mdata->type) + *cmt = NULL; + else if (mdata->CommentLength) { + *cmt = (char *) XpmMalloc(mdata->CommentLength + 1); + strncpy(*cmt, mdata->Comment, mdata->CommentLength); + (*cmt)[mdata->CommentLength] = '\0'; + mdata->CommentLength = 0; + } else + *cmt = NULL; + return 0; +} + +/* + * open the given file to be read as an xpmData which is returned. + */ +int +xpmReadFile(char *filename, xpmData *mdata) +{ +#ifdef ZPIPE + char *compressfile, buf[BUFSIZ]; + struct stat status; + +#endif + + if (!filename) { + mdata->stream.file = (stdin); + mdata->type = XPMFILE; + } else { +#ifdef ZPIPE + if (((int) strlen(filename) > 2) && + !strcmp(".Z", filename + (strlen(filename) - 2))) { + mdata->type = XPMPIPE; + sprintf(buf, "uncompress -c %s", filename); + if (!(mdata->stream.file = popen(buf, "r"))) + return (XpmOpenFailed); + + } else if (((int) strlen(filename) > 3) && + !strcmp(".gz", filename + (strlen(filename) - 3))) { + mdata->type = XPMPIPE; + sprintf(buf, "gunzip -qc %s", filename); + if (!(mdata->stream.file = popen(buf, "r"))) + return (XpmOpenFailed); + + } else { + if (!(compressfile = (char *) XpmMalloc(strlen(filename) + 4))) + return (XpmNoMemory); + + strcpy(compressfile, filename); + strcat(compressfile, ".Z"); + if (!stat(compressfile, &status)) { + sprintf(buf, "uncompress -c %s", compressfile); + if (!(mdata->stream.file = popen(buf, "r"))) { + XpmFree(compressfile); + return (XpmOpenFailed); + } + mdata->type = XPMPIPE; + } else { + strcpy(compressfile, filename); + strcat(compressfile, ".gz"); + if (!stat(compressfile, &status)) { + sprintf(buf, "gunzip -c %s", compressfile); + if (!(mdata->stream.file = popen(buf, "r"))) { + XpmFree(compressfile); + return (XpmOpenFailed); + } + mdata->type = XPMPIPE; + } else { +#endif + if (!(mdata->stream.file = fopen(filename, "r"))) { +#ifdef ZPIPE + XpmFree(compressfile); +#endif + return (XpmOpenFailed); + } + mdata->type = XPMFILE; +#ifdef ZPIPE + } + } + XpmFree(compressfile); + } +#endif + } + mdata->CommentLength = 0; + return (XpmSuccess); +} + +/* + * open the given file to be written as an xpmData which is returned + */ +int +xpmWriteFile(char *filename, xpmData *mdata) +{ +#ifdef ZPIPE + char buf[BUFSIZ]; + +#endif + + if (!filename) { + mdata->stream.file = (stdout); + mdata->type = XPMFILE; + } else { +#ifdef ZPIPE + if ((int) strlen(filename) > 2 + && !strcmp(".Z", filename + (strlen(filename) - 2))) { + sprintf(buf, "compress > %s", filename); + if (!(mdata->stream.file = popen(buf, "w"))) + return (XpmOpenFailed); + + mdata->type = XPMPIPE; + } else if ((int) strlen(filename) > 3 + && !strcmp(".gz", filename + (strlen(filename) - 3))) { + sprintf(buf, "gzip -q > %s", filename); + if (!(mdata->stream.file = popen(buf, "w"))) + return (XpmOpenFailed); + + mdata->type = XPMPIPE; + } else { +#endif + if (!(mdata->stream.file = fopen(filename, "w"))) + return (XpmOpenFailed); + + mdata->type = XPMFILE; +#ifdef ZPIPE + } +#endif + } + return (XpmSuccess); +} + +/* + * open the given array to be read or written as an xpmData which is returned + */ +void +xpmOpenArray(char **data, xpmData *mdata) +{ + mdata->type = XPMARRAY; + mdata->stream.data = data; + mdata->cptr = *data; + mdata->line = 0; + mdata->CommentLength = 0; + mdata->Bcmt = mdata->Ecmt = NULL; + mdata->Bos = mdata->Eos = '\0'; + mdata->format = 0; /* this can only be Xpm 2 or 3 */ +} + +/* + * open the given buffer to be read or written as an xpmData which is returned + */ +void +xpmOpenBuffer(char *buffer, xpmData *mdata) +{ + mdata->type = XPMBUFFER; + mdata->cptr = buffer; + mdata->CommentLength = 0; +} + +/* + * close the file related to the xpmData if any + */ +int +xpmDataClose(xpmData *mdata) +{ + switch (mdata->type) { + case XPMARRAY: + case XPMBUFFER: + break; + case XPMFILE: + if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin)) + fclose(mdata->stream.file); + break; +#ifdef ZPIPE + case XPMPIPE: + pclose(mdata->stream.file); + break; +#endif + } + return 0; +} + +xpmDataType xpmDataTypes[] = +{ + "", "!", "\n", '\0', '\n', "", "", "", "", /* Natural type */ + "C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n", + "Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n", +#ifdef VMS + NULL +#else + NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL +#endif +}; + +/* + * parse xpm header + */ +int +xpmParseHeader(xpmData *mdata) +{ + char buf[BUFSIZ]; + int l, n = 0; + + if (mdata->type) { + mdata->Bos = '\0'; + mdata->Eos = '\n'; + mdata->Bcmt = mdata->Ecmt = NULL; + l = xpmNextWord(mdata, buf, BUFSIZ); + if (l == 7 && !strncmp("#define", buf, 7)) { + /* this maybe an XPM 1 file */ + char *ptr; + + l = xpmNextWord(mdata, buf, BUFSIZ); + if (!l) + return (XpmFileInvalid); + ptr = strchr(buf, '_'); + if (!ptr || strncmp("_format", ptr, l - (ptr - buf))) + return XpmFileInvalid; + /* this is definitely an XPM 1 file */ + mdata->format = 1; + n = 1; /* handle XPM1 as mainly XPM2 C */ + } else { + + /* + * skip the first word, get the second one, and see if this is + * XPM 2 or 3 + */ + l = xpmNextWord(mdata, buf, BUFSIZ); + if ((l == 3 && !strncmp("XPM", buf, 3)) || + (l == 4 && !strncmp("XPM2", buf, 4))) { + if (l == 3) + n = 1; /* handle XPM as XPM2 C */ + else { + /* get the type key word */ + l = xpmNextWord(mdata, buf, BUFSIZ); + + /* + * get infos about this type + */ + while (xpmDataTypes[n].type + && strncmp(xpmDataTypes[n].type, buf, l)) + n++; + } + mdata->format = 0; + } else + /* nope this is not an XPM file */ + return XpmFileInvalid; + } + if (xpmDataTypes[n].type) { + if (n == 0) { /* natural type */ + mdata->Bcmt = xpmDataTypes[n].Bcmt; + mdata->Ecmt = xpmDataTypes[n].Ecmt; + xpmNextString(mdata); /* skip the end of the headerline */ + mdata->Bos = xpmDataTypes[n].Bos; + mdata->Eos = xpmDataTypes[n].Eos; + } else { + mdata->Bcmt = xpmDataTypes[n].Bcmt; + mdata->Ecmt = xpmDataTypes[n].Ecmt; + if (!mdata->format) { /* XPM 2 or 3 */ + mdata->Bos = xpmDataTypes[n].Bos; + mdata->Eos = '\0'; + /* get to the beginning of the first string */ + xpmNextString(mdata); + mdata->Eos = xpmDataTypes[n].Eos; + } else /* XPM 1 skip end of line */ + xpmNextString(mdata); + } + } else + /* we don't know about that type of XPM file... */ + return XpmFileInvalid; + } + return XpmSuccess; +} diff --git a/src/xpm/files b/src/xpm/files new file mode 100644 index 0000000000..0a98c41644 --- /dev/null +++ b/src/xpm/files @@ -0,0 +1,47 @@ +CHANGES +COPYRIGHT +FILES +Imakefile +Makefile.noXtree +README +README.MSW +namecvt +lib +lib/Imakefile +lib/Makefile.noXtree +lib/XpmCrBufFrI.c +lib/XpmCrBufFrP.c +lib/XpmCrDataFrI.c +lib/XpmCrDataFrP.c +lib/XpmCrIFrBuf.c +lib/XpmCrIFrData.c +lib/XpmCrPFrBuf.c +lib/XpmCrPFrData.c +lib/XpmRdFToData.c +lib/XpmRdFToI.c +lib/XpmRdFToP.c +lib/XpmWrFFrData.c +lib/XpmWrFFrI.c +lib/XpmWrFFrP.c +lib/create.c +lib/data.c +lib/hashtable.c +lib/misc.c +lib/parse.c +lib/rgb.c +lib/rgbtab.h +lib/scan.c +lib/simx.h +lib/simx.c +lib/xpm.h +lib/xpmP.h +doc +doc/xpm.ps +sxpm +sxpm/Imakefile +sxpm/Makefile.noXtree +sxpm/plaid.xpm +sxpm/plaid_ext.xpm +sxpm/plaid_mask.xpm +sxpm/sxpm.c +sxpm/sxpm.man diff --git a/src/xpm/hashtab.c b/src/xpm/hashtab.c new file mode 100644 index 0000000000..6efa9708b8 --- /dev/null +++ b/src/xpm/hashtab.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* hashtable.c: * +* * +* XPM library * +* * +* Developed by Arnaud Le Hors * +* this originaly comes from Colas Nahaboo as a part of Wool * +* * +\*****************************************************************************/ + +#include "xpm34p.h" + +LFUNC(AtomMake, xpmHashAtom, (char *name, void *data)); +LFUNC(HashTableGrows, int, (xpmHashTable * table)); + +static xpmHashAtom +AtomMake(char *name, void *data) /* makes an atom */ +/* char *name; */ /* WARNING: is just pointed to */ +/* void *data; */ +{ + xpmHashAtom object = (xpmHashAtom) XpmMalloc(sizeof(struct _xpmHashAtom)); + + if (object) { + object->name = name; + object->data = data; + } + return object; +} + +/************************\ +* * +* hash table routines * +* * +\************************/ + +/* + * Hash function definition: + * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char, + * hash2 = temporary for hashcode. + * INITIAL_TABLE_SIZE in slots + * HASH_TABLE_GROWS how hash table grows. + */ + +/* Mock lisp function */ +#define HASH_FUNCTION hash = (hash << 5) - hash + *hp++; +/* #define INITIAL_HASH_SIZE 2017 */ +#define INITIAL_HASH_SIZE 256 /* should be enough for colors */ +#define HASH_TABLE_GROWS size = size * 2; + +/* aho-sethi-ullman's HPJ (sizes should be primes)*/ +#ifdef notdef +#define HASH_FUNCTION hash <<= 4; hash += *hp++; \ + if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2; +#define INITIAL_HASH_SIZE 4095 /* should be 2^n - 1 */ +#define HASH_TABLE_GROWS size = size << 1 + 1; +#endif + +/* GNU emacs function */ +/* +#define HASH_FUNCTION hash = (hash << 3) + (hash >> 28) + *hp++; +#define INITIAL_HASH_SIZE 2017 +#define HASH_TABLE_GROWS size = size * 2; +*/ + +/* end of hash functions */ + +/* + * The hash table is used to store atoms via their NAME: + * + * NAME --hash--> ATOM |--name--> "foo" + * |--data--> any value which has to be stored + * + */ + +/* + * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name + * (slot points to NULL if it is not defined) + * + */ + +xpmHashAtom * +xpmHashSlot(xpmHashTable *table, char *s) +{ + xpmHashAtom *atomTable = table->atomTable; + unsigned int hash; + xpmHashAtom *p; + char *hp = s; + char *ns; + + hash = 0; + while (*hp) { /* computes hash function */ + HASH_FUNCTION + } + p = atomTable + hash % table->size; + while (*p) { + ns = (*p)->name; + if (ns[0] == s[0] && strcmp(ns, s) == 0) + break; + p--; + if (p < atomTable) + p = atomTable + table->size - 1; + } + return p; +} + +static int +HashTableGrows(xpmHashTable *table) +{ + xpmHashAtom *atomTable = table->atomTable; + int size = table->size; + xpmHashAtom *t, *p; + int i; + int oldSize = size; + + t = atomTable; + HASH_TABLE_GROWS + table->size = size; + table->limit = size / 3; + atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable)); + if (!atomTable) + return (XpmNoMemory); + table->atomTable = atomTable; + for (p = atomTable + size; p > atomTable;) + *--p = NULL; + for (i = 0, p = t; i < oldSize; i++, p++) + if (*p) { + xpmHashAtom *ps = xpmHashSlot(table, (*p)->name); + + *ps = *p; + } + XpmFree(t); + return (XpmSuccess); +} + +/* + * xpmHashIntern(table, name, data) + * an xpmHashAtom is created if name doesn't exist, with the given data. + */ + +int +xpmHashIntern(xpmHashTable *table, char *tag, void *data) +{ + xpmHashAtom *slot; + + if (!*(slot = xpmHashSlot(table, tag))) { + /* undefined, make a new atom with the given data */ + if (!(*slot = AtomMake(tag, data))) + return (XpmNoMemory); + if (table->used >= table->limit) { + int ErrorStatus; + + if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess) + return (ErrorStatus); + table->used++; + return (XpmSuccess); + } + table->used++; + } + return (XpmSuccess); +} + +/* + * must be called before allocating any atom + */ + +int +xpmHashTableInit(xpmHashTable *table) +{ + xpmHashAtom *p; + xpmHashAtom *atomTable; + + table->size = INITIAL_HASH_SIZE; + table->limit = table->size / 3; + table->used = 0; + atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable)); + if (!atomTable) + return (XpmNoMemory); + for (p = atomTable + table->size; p > atomTable;) + *--p = NULL; + table->atomTable = atomTable; + return (XpmSuccess); +} + +/* + * frees a hashtable and all the stored atoms + */ + +void +xpmHashTableFree(xpmHashTable *table) +{ + xpmHashAtom *p; + xpmHashAtom *atomTable = table->atomTable; + + for (p = atomTable + table->size; p > atomTable;) + if (*--p) + XpmFree(*p); + XpmFree(atomTable); + table->atomTable = NULL; +} diff --git a/src/xpm/misc.c b/src/xpm/misc.c new file mode 100644 index 0000000000..c0089ab011 --- /dev/null +++ b/src/xpm/misc.c @@ -0,0 +1,572 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* misc.c: * +* * +* XPM library * +* Miscellaneous utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:stat.h" +#include "sys$library:fcntl.h" +#else +#include +#include +#include +#include +#ifdef FOR_MSW +#include +#else +#include +#endif +#endif + +/* 3.2 backward compatibility code */ +LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors, + XpmColor ***oldct)); + +LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors)); + +/* + * Create a colortable compatible with the old style colortable + */ +static int +CreateOldColorTable(XpmColor *ct, int ncolors, XpmColor ***oldct) +{ + XpmColor **colorTable, **color; + int a; + + colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *)); + if (!colorTable) { + *oldct = NULL; + return (XpmNoMemory); + } + for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++) + *color = ct; + *oldct = colorTable; + return (XpmSuccess); +} + +static void +FreeOldColorTable(XpmColor **colorTable, int ncolors) +{ + int a, b; + XpmColor **color; + char **sptr; + + if (colorTable) { + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++) + if (*sptr) + XpmFree(*sptr); + } + XpmFree(*colorTable); + XpmFree(colorTable); + } +} + +/* end 3.2 bc */ + + +/* + * Free the computed color table + */ +void +xpmFreeColorTable(XpmColor *colorTable, int ncolors) +{ + int a, b; + XpmColor *color; + char **sptr; + + if (colorTable) { + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++) + if (*sptr) + XpmFree(*sptr); + } + XpmFree(colorTable); + } +} + +/* + * Free array of extensions + */ +void +XpmFreeExtensions(XpmExtension *extensions, int nextensions) +{ + unsigned int i, j, nlines; + XpmExtension *ext; + char **sptr; + + if (extensions) { + for (i = 0, ext = extensions; i < nextensions; i++, ext++) { + if (ext->name) + XpmFree(ext->name); + nlines = ext->nlines; + for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++) + if (*sptr) + XpmFree(*sptr); + if (ext->lines) + XpmFree(ext->lines); + } + XpmFree(extensions); + } +} + + +/* + * Return the XpmAttributes structure size + */ + +int +XpmAttributesSize() +{ + return sizeof(XpmAttributes); +} + +/* + * Init returned data to free safely later on + */ +void +xpmInitAttributes(XpmAttributes *attributes) +{ + if (attributes) { + attributes->pixels = NULL; + attributes->npixels = 0; + attributes->colorTable = NULL; + attributes->ncolors = 0; +/* 3.2 backward compatibility code */ + attributes->hints_cmt = NULL; + attributes->colors_cmt = NULL; + attributes->pixels_cmt = NULL; +/* end 3.2 bc */ + attributes->extensions = NULL; + attributes->nextensions = 0; + } +} + +/* + * Fill in the XpmAttributes with the XpmImage and the XpmInfo + */ +void +xpmSetAttributes(XpmAttributes *attributes, XpmImage *image, XpmInfo *info) +{ + if (attributes->valuemask & XpmReturnColorTable) { + attributes->colorTable = image->colorTable; + attributes->ncolors = image->ncolors; + + /* avoid deletion of copied data */ + image->ncolors = 0; + image->colorTable = NULL; + } +/* 3.2 backward compatibility code */ + else if (attributes->valuemask & XpmReturnInfos) { + int ErrorStatus; + + ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors, + (XpmColor ***) + &attributes->colorTable); + + /* if error just say we can't return requested data */ + if (ErrorStatus != XpmSuccess) { + attributes->valuemask &= ~XpmReturnInfos; + if (!(attributes->valuemask & XpmReturnPixels)) { + XpmFree(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + attributes->ncolors = 0; + } else { + attributes->ncolors = image->ncolors; + attributes->hints_cmt = info->hints_cmt; + attributes->colors_cmt = info->colors_cmt; + attributes->pixels_cmt = info->pixels_cmt; + + /* avoid deletion of copied data */ + image->ncolors = 0; + image->colorTable = NULL; + info->hints_cmt = NULL; + info->colors_cmt = NULL; + info->pixels_cmt = NULL; + } + } +/* end 3.2 bc */ + if (attributes->valuemask & XpmReturnExtensions) { + attributes->extensions = info->extensions; + attributes->nextensions = info->nextensions; + + /* avoid deletion of copied data */ + info->extensions = NULL; + info->nextensions = 0; + } + if (info->valuemask & XpmHotspot) { + attributes->valuemask |= XpmHotspot; + attributes->x_hotspot = info->x_hotspot; + attributes->y_hotspot = info->y_hotspot; + } + attributes->valuemask |= XpmCharsPerPixel; + attributes->cpp = image->cpp; + attributes->valuemask |= XpmSize; + attributes->width = image->width; + attributes->height = image->height; +} + +/* + * Free the XpmAttributes structure members + * but the structure itself + */ +void +XpmFreeAttributes(XpmAttributes *attributes) +{ + if (attributes->valuemask & XpmReturnPixels && attributes->npixels) { + XpmFree(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + if (attributes->valuemask & XpmReturnColorTable) { + xpmFreeColorTable(attributes->colorTable, attributes->ncolors); + attributes->colorTable = NULL; + attributes->ncolors = 0; + } +/* 3.2 backward compatibility code */ + else if (attributes->valuemask & XpmInfos) { + if (attributes->colorTable) { + FreeOldColorTable((XpmColor **) attributes->colorTable, + attributes->ncolors); + attributes->colorTable = NULL; + attributes->ncolors = 0; + } + if (attributes->hints_cmt) { + XpmFree(attributes->hints_cmt); + attributes->hints_cmt = NULL; + } + if (attributes->colors_cmt) { + XpmFree(attributes->colors_cmt); + attributes->colors_cmt = NULL; + } + if (attributes->pixels_cmt) { + XpmFree(attributes->pixels_cmt); + attributes->pixels_cmt = NULL; + } + if (attributes->pixels) { + XpmFree(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + } +/* end 3.2 bc */ + if (attributes->valuemask & XpmReturnExtensions + && attributes->nextensions) { + XpmFreeExtensions(attributes->extensions, attributes->nextensions); + attributes->extensions = NULL; + attributes->nextensions = 0; + } + attributes->valuemask = 0; +} + +/* + * Init returned data to free safely later on + */ +void +xpmInitXpmImage(XpmImage *image) +{ + image->ncolors = 0; + image->colorTable = NULL; + image->data = NULL; +} + +/* + * Free the XpmImage data which have been allocated + */ +void +XpmFreeXpmImage(XpmImage *image) +{ + if (image->colorTable) + xpmFreeColorTable(image->colorTable, image->ncolors); + XpmFree(image->data); + image->data = NULL; +} + +/* + * Init returned data to free safely later on + */ +void +xpmInitXpmInfo(XpmInfo *info) +{ + if (info) { + info->hints_cmt = NULL; + info->colors_cmt = NULL; + info->pixels_cmt = NULL; + info->extensions = NULL; + info->nextensions = 0; + } +} + +/* + * Free the XpmInfo data which have been allocated + */ +void +XpmFreeXpmInfo(XpmInfo *info) +{ + if (info) { + if (info->valuemask & XpmComments) { + if (info->hints_cmt) { + XpmFree(info->hints_cmt); + info->hints_cmt = NULL; + } + if (info->colors_cmt) { + XpmFree(info->colors_cmt); + info->colors_cmt = NULL; + } + if (info->pixels_cmt) { + XpmFree(info->pixels_cmt); + info->pixels_cmt = NULL; + } + } + if (info->valuemask & XpmReturnExtensions && info->nextensions) { + XpmFreeExtensions(info->extensions, info->nextensions); + info->extensions = NULL; + info->nextensions = 0; + } + info->valuemask = 0; + } +} + +/* + * Set the XpmInfo valuemask to retrieve required info + */ +void +xpmSetInfoMask(XpmInfo *info, XpmAttributes *attributes) +{ + info->valuemask = 0; + if (attributes->valuemask & XpmReturnInfos) + info->valuemask |= XpmReturnComments; + if (attributes->valuemask & XpmReturnExtensions) + info->valuemask |= XpmReturnExtensions; +} + +/* + * Fill in the XpmInfo with the XpmAttributes + */ +void +xpmSetInfo(XpmInfo *info, XpmAttributes *attributes) +{ + info->valuemask = 0; + if (attributes->valuemask & XpmInfos) { + info->valuemask |= XpmComments | XpmColorTable; + info->hints_cmt = attributes->hints_cmt; + info->colors_cmt = attributes->colors_cmt; + info->pixels_cmt = attributes->pixels_cmt; + } + if (attributes->valuemask & XpmExtensions) { + info->valuemask |= XpmExtensions; + info->extensions = attributes->extensions; + info->nextensions = attributes->nextensions; + } + if (attributes->valuemask & XpmHotspot) { + info->valuemask |= XpmHotspot; + info->x_hotspot = attributes->x_hotspot; + info->y_hotspot = attributes->y_hotspot; + } +} + + +#ifdef NEED_STRDUP +/* + * in case strdup is not provided by the system here is one + * which does the trick + */ +char * +strdup(char *s1) +{ + char *s2; + int l = strlen(s1) + 1; + + if (s2 = (char *) XpmMalloc(l)) + strncpy(s2, s1, l); + return s2; +} + +#endif + +unsigned int +atoui(register char *p, unsigned int l, unsigned int *ui_return) +{ + register unsigned int n, i; + + n = 0; + for (i = 0; i < l; i++) + if (*p >= '0' && *p <= '9') + n = n * 10 + *p++ - '0'; + else + break; + + if (i != 0 && i == l) { + *ui_return = n; + return 1; + } else + return 0; +} + + +/* + * File / Buffer utilities + */ +int +XpmReadFileToBuffer(char *filename, char **buffer_return) +{ + int fd, fcheck, len; + char *ptr; + struct stat stats; + FILE *fp; + + *buffer_return = NULL; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return XpmOpenFailed; + + if (fstat(fd, &stats)) { + close(fd); + return XpmOpenFailed; + } + fp = fdopen(fd, "r"); + if (!fp) { + close(fd); + return XpmOpenFailed; + } + len = (int) stats.st_size; + ptr = (char *) XpmMalloc(len + 1); + if (!ptr) { + fclose(fp); + return XpmNoMemory; + } + fcheck = fread(ptr, len, 1, fp); + fclose(fp); + if (fcheck != 1) { + XpmFree(ptr); + return XpmOpenFailed; + } + ptr[len] = '\0'; + *buffer_return = ptr; + return XpmSuccess; +} + +int +XpmWriteFileFromBuffer(char *filename, char *buffer) +{ + int fcheck, len; + FILE *fp = fopen(filename, "w"); + + if (!fp) + return XpmOpenFailed; + + len = strlen(buffer); + fcheck = fwrite(buffer, len, 1, fp); + fclose(fp); + if (fcheck != 1) + return XpmOpenFailed; + + return XpmSuccess; +} + + +/* + * Small utility function + */ +char * +XpmGetErrorString(int errcode) +{ + switch (errcode) { + case XpmColorError: + return ("XpmColorError"); + case XpmSuccess: + return ("XpmSuccess"); + case XpmOpenFailed: + return ("XpmOpenFailed"); + case XpmFileInvalid: + return ("XpmFileInvalid"); + case XpmNoMemory: + return ("XpmNoMemory"); + case XpmColorFailed: + return ("XpmColorFailed"); + default: + return ("Invalid XpmError"); + } +} + +/* + * The following function provides a way to figure out if the linked library is + * newer or older than the one with which a program has been first compiled. + */ +int +XpmLibraryVersion() +{ + return XpmIncludeVersion; +} + + +#ifndef FOR_MSW +void +xpmCreatePixmapFromImage(Display *display, Drawable d, XImage *ximage, Pixmap *pixmap_return) +{ + GC gc; + + *pixmap_return = XCreatePixmap(display, d, ximage->width, + ximage->height, ximage->depth); + gc = XCreateGC(display, *pixmap_return, 0, NULL); + + XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0, + ximage->width, ximage->height); + + XFreeGC(display, gc); +} + +void +xpmCreateImageFromPixmap(Display *display, Pixmap pixmap, XImage **ximage_return, unsigned int *width, unsigned int *height) +{ + unsigned int dum; + int dummy; + Window win; + + if (*width == 0 && *height == 0) + XGetGeometry(display, pixmap, &win, &dummy, &dummy, + width, height, &dum, &dum); + + *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height, + AllPlanes, ZPixmap); +} + +#endif /* FOR_MSW */ diff --git a/src/xpm/parse.c b/src/xpm/parse.c new file mode 100644 index 0000000000..17f8ed27f6 --- /dev/null +++ b/src/xpm/parse.c @@ -0,0 +1,704 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* parse.c: * +* * +* XPM library * +* Parse an XPM file or array and store the found informations * +* in the given XpmImage structure. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:ctype.h" +#else +#include +#endif + +#ifdef sun +#ifdef SVR4 +#include /* bzero, bcopy */ +#endif +#endif + +#include +#ifdef __sgi +#include +#endif + +LFUNC(ParseValues, int, (xpmData *data, unsigned int *width, + unsigned int *height, unsigned int *ncolors, + unsigned int *cpp, unsigned int *x_hotspot, + unsigned int *y_hotspot, unsigned int *hotspot, + unsigned int *extensions)); + +LFUNC(ParseColors, int, (xpmData *data, unsigned int ncolors, unsigned int cpp, + XpmColor **colorTablePtr, xpmHashTable *hashtable)); + +LFUNC(ParsePixels, int, (xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, unsigned int **pixels)); + +LFUNC(ParseExtensions, int, (xpmData *data, XpmExtension **extensions, + unsigned int *nextensions)); + +char *xpmColorKeys[] = { + "s", /* key #1: symbol */ + "m", /* key #2: mono visual */ + "g4", /* key #3: 4 grays visual */ + "g", /* key #4: gray visual */ + "c", /* key #5: color visual */ +}; + + +/* function call in case of error, frees only locally allocated variables */ +#undef RETURN +#define RETURN(status) \ +{ \ + if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ + if (pixelindex) XpmFree(pixelindex); \ + if (hints_cmt) XpmFree(hints_cmt); \ + if (colors_cmt) XpmFree(colors_cmt); \ + if (pixels_cmt) XpmFree(pixels_cmt); \ + return(status); \ +} + +/* + * This function parses an Xpm file or data and store the found informations + * in an an XpmImage structure which is returned. + */ +int +xpmParseData(xpmData *data, XpmImage *image, XpmInfo *info) +{ + /* variables to return */ + unsigned int width, height, ncolors, cpp; + unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; + XpmColor *colorTable = NULL; + unsigned int *pixelindex = NULL; + char *hints_cmt = NULL; + char *colors_cmt = NULL; + char *pixels_cmt = NULL; + + unsigned int cmts; + int ErrorStatus; + xpmHashTable hashtable; + + cmts = info && (info->valuemask & XpmReturnComments); + + /* + * parse the header + */ + ErrorStatus = xpmParseHeader(data); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * read values + */ + ErrorStatus = ParseValues(data, &width, &height, &ncolors, &cpp, + &x_hotspot, &y_hotspot, &hotspot, &extensions); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * store the hints comment line + */ + if (cmts) + xpmGetCmt(data, &hints_cmt); + + /* + * init the hastable + */ + if (USE_HASHTABLE) { + ErrorStatus = xpmHashTableInit(&hashtable); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + } + + /* + * read colors + */ + ErrorStatus = ParseColors(data, ncolors, cpp, &colorTable, &hashtable); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the colors comment line + */ + if (cmts) + xpmGetCmt(data, &colors_cmt); + + /* + * read pixels and index them on color number + */ + ErrorStatus = ParsePixels(data, width, height, ncolors, cpp, colorTable, + &hashtable, &pixelindex); + + /* + * free the hastable + */ + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the pixels comment line + */ + if (cmts) + xpmGetCmt(data, &pixels_cmt); + + /* + * parse extensions + */ + if (info && (info->valuemask & XpmReturnExtensions)) + if (extensions) { + ErrorStatus = ParseExtensions(data, &info->extensions, + &info->nextensions); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } else { + info->extensions = NULL; + info->nextensions = 0; + } + + /* + * store found informations in the XpmImage structure + */ + image->width = width; + image->height = height; + image->cpp = cpp; + image->ncolors = ncolors; + image->colorTable = colorTable; + image->data = pixelindex; + + if (info) { + if (cmts) { + info->hints_cmt = hints_cmt; + info->colors_cmt = colors_cmt; + info->pixels_cmt = pixels_cmt; + } + if (hotspot) { + info->x_hotspot = x_hotspot; + info->y_hotspot = y_hotspot; + info->valuemask |= XpmHotspot; + } + } + return (XpmSuccess); +} + +static int +ParseValues(xpmData *data, unsigned int *width, unsigned int *height, unsigned int *ncolors, unsigned int *cpp, + unsigned int *x_hotspot, unsigned int *y_hotspot, unsigned int *hotspot, unsigned int *extensions) +{ + unsigned int l; + char buf[BUFSIZ]; + + if (!data->format) { /* XPM 2 or 3 */ + + /* + * read values: width, height, ncolors, chars_per_pixel + */ + if (!(xpmNextUI(data, width) && xpmNextUI(data, height) + && xpmNextUI(data, ncolors) && xpmNextUI(data, cpp))) + return (XpmFileInvalid); + + /* + * read optional information (hotspot and/or XPMEXT) if any + */ + l = xpmNextWord(data, buf, BUFSIZ); + if (l) { + *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6)); + if (*extensions) + *hotspot = (xpmNextUI(data, x_hotspot) + && xpmNextUI(data, y_hotspot)); + else { + *hotspot = (atoui(buf, l, x_hotspot) + && xpmNextUI(data, y_hotspot)); + l = xpmNextWord(data, buf, BUFSIZ); + *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6)); + } + } + } else { + + /* + * XPM 1 file read values: width, height, ncolors, chars_per_pixel + */ + int i; + char *ptr; + + for (i = 0; i < 4; i++) { + l = xpmNextWord(data, buf, BUFSIZ); + if (l != 7 || strncmp("#define", buf, 7)) + return (XpmFileInvalid); + l = xpmNextWord(data, buf, BUFSIZ); + if (!l) + return (XpmFileInvalid); + ptr = strchr(buf, '_'); + if (!ptr) + return (XpmFileInvalid); + switch (l - (ptr - buf)) { + case 6: + if (!strncmp("_width", ptr, 6) && !xpmNextUI(data, width)) + return (XpmFileInvalid); + break; + case 7: + if (!strncmp("_height", ptr, 7) && !xpmNextUI(data, height)) + return (XpmFileInvalid); + break; + case 8: + if (!strncmp("_ncolors", ptr, 8) && !xpmNextUI(data, ncolors)) + return (XpmFileInvalid); + break; + case 16: + if (!strncmp("_chars_per_pixel", ptr, 16) + && !xpmNextUI(data, cpp)) + return (XpmFileInvalid); + break; + default: + return (XpmFileInvalid); + } + /* skip the end of line */ + xpmNextString(data); + } + *hotspot = 0; + *extensions = 0; + } + return (XpmSuccess); +} + +static int +ParseColors(xpmData *data, unsigned int ncolors, unsigned int cpp, XpmColor **colorTablePtr, xpmHashTable *hashtable) +{ + unsigned int key, l, a, b; + unsigned int curkey; /* current color key */ + unsigned int lastwaskey; /* key read */ + char buf[BUFSIZ]; + char curbuf[BUFSIZ]; /* current buffer */ + char **sptr, *s; + XpmColor *color; + XpmColor *colorTable; + char **defaults; + int ErrorStatus; + + colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor)); + if (!colorTable) + return (XpmNoMemory); + + if (!data->format) { /* XPM 2 or 3 */ + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + xpmNextString(data); /* skip the line */ + + /* + * read pixel value + */ + color->string = (char *) XpmMalloc(cpp + 1); + if (!color->string) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + for (b = 0, s = color->string; b < cpp; b++, s++) + *s = xpmGetC(data); + *s = '\0'; + + /* + * store the string in the hashtable with its color index number + */ + if (USE_HASHTABLE) { + ErrorStatus = + xpmHashIntern(hashtable, color->string, HashAtomData(a)); + if (ErrorStatus != XpmSuccess) { + xpmFreeColorTable(colorTable, ncolors); + return (ErrorStatus); + } + } + + /* + * read color keys and values + */ + defaults = (char **) color; + curkey = 0; + lastwaskey = 0; + *curbuf = '\0'; /* init curbuf */ + while (l = xpmNextWord(data, buf, BUFSIZ)) { + if (!lastwaskey) { + for (key = 0, sptr = xpmColorKeys; key < NKEYS; key++, + sptr++) + if ((strlen(*sptr) == l) && (!strncmp(*sptr, buf, l))) + break; + } + if (!lastwaskey && key < NKEYS) { /* open new key */ + if (curkey) { /* flush string */ + s = (char *) XpmMalloc(strlen(curbuf) + 1); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + defaults[curkey] = s; + strcpy(s, curbuf); + } + curkey = key + 1; /* set new key */ + *curbuf = '\0'; /* reset curbuf */ + lastwaskey = 1; + } else { + if (!curkey) { /* key without value */ + xpmFreeColorTable(colorTable, ncolors); + return (XpmFileInvalid); + } + if (!lastwaskey) + strcat(curbuf, " "); /* append space */ + buf[l] = '\0'; + strcat(curbuf, buf);/* append buf */ + lastwaskey = 0; + } + } + if (!curkey) { /* key without value */ + xpmFreeColorTable(colorTable, ncolors); + return (XpmFileInvalid); + } + s = defaults[curkey] = (char *) XpmMalloc(strlen(curbuf) + 1); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + strcpy(s, curbuf); + } + } else { /* XPM 1 */ + /* get to the beginning of the first string */ + data->Bos = '"'; + data->Eos = '\0'; + xpmNextString(data); + data->Eos = '"'; + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + + /* + * read pixel value + */ + color->string = (char *) XpmMalloc(cpp + 1); + if (!color->string) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + for (b = 0, s = color->string; b < cpp; b++, s++) + *s = xpmGetC(data); + *s = '\0'; + + /* + * store the string in the hashtable with its color index number + */ + if (USE_HASHTABLE) { + ErrorStatus = + xpmHashIntern(hashtable, color->string, HashAtomData(a)); + if (ErrorStatus != XpmSuccess) { + xpmFreeColorTable(colorTable, ncolors); + return (ErrorStatus); + } + } + + /* + * read color values + */ + xpmNextString(data); /* get to the next string */ + *curbuf = '\0'; /* init curbuf */ + while (l = xpmNextWord(data, buf, BUFSIZ)) { + if (*curbuf != '\0') + strcat(curbuf, " ");/* append space */ + buf[l] = '\0'; + strcat(curbuf, buf); /* append buf */ + } + s = (char *) XpmMalloc(strlen(curbuf) + 1); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + strcpy(s, curbuf); + color->c_color = s; + *curbuf = '\0'; /* reset curbuf */ + if (a < ncolors - 1) + xpmNextString(data); /* get to the next string */ + } + } + *colorTablePtr = colorTable; + return (XpmSuccess); +} + +static int +ParsePixels(xpmData *data, unsigned int width, unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, xpmHashTable *hashtable, unsigned int **pixels) +{ + unsigned int *iptr, *iptr2; + unsigned int a, x, y; + +#ifndef FOR_MSW + iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height); +#else + + /* + * special treatment to trick DOS malloc(size_t) where size_t is 16 bit!! + * XpmMalloc is defined to longMalloc(long) and checks the 16 bit boundary + */ + iptr2 = (unsigned int *) + XpmMalloc((long) sizeof(unsigned int) * (long) width * (long) height); +#endif + if (!iptr2) + return (XpmNoMemory); + + iptr = iptr2; + + switch (cpp) { + + case (1): /* Optimize for single character + * colors */ + { + unsigned short colidx[256]; + + bzero((char *)colidx, 256 * sizeof(short)); + for (a = 0; a < ncolors; a++) + colidx[colorTable[a].string[0]] = a + 1; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + int idx = colidx[xpmGetC(data)]; + + if (idx != 0) + *iptr = idx - 1; + else { + XpmFree(iptr2); + return (XpmFileInvalid); + } + } + } + } + break; + + case (2): /* Optimize for double character + * colors */ + { + +/* free all allocated pointers at all exits */ +#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \ +if (cidx[f]) XpmFree(cidx[f]);} + + /* array of pointers malloced by need */ + unsigned short *cidx[256]; + int char1; + + bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ + for (a = 0; a < ncolors; a++) { + char1 = colorTable[a].string[0]; + if (cidx[char1] == NULL) { /* get new memory */ + cidx[char1] = (unsigned short *) + XpmCalloc(256, sizeof(unsigned short)); + if (cidx[char1] == NULL) { /* new block failed */ + FREE_CIDX; + XpmFree(iptr2); + return (XpmNoMemory); + } + } + cidx[char1][colorTable[a].string[1]] = a + 1; + } + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + int cc1 = xpmGetC(data); + int idx = cidx[cc1][xpmGetC(data)]; + + if (idx != 0) + *iptr = idx - 1; + else { + FREE_CIDX; + XpmFree(iptr2); + return (XpmFileInvalid); + } + } + } + FREE_CIDX; + } + break; + + default: /* Non-optimized case of long color + * names */ + { + char *s; + char buf[BUFSIZ]; + + buf[cpp] = '\0'; + if (USE_HASHTABLE) { + xpmHashAtom *slot; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + slot = xpmHashSlot(hashtable, buf); + if (!*slot) { /* no color matches */ + XpmFree(iptr2); + return (XpmFileInvalid); + } + *iptr = HashColorIndex(slot); + } + } + } else { + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + for (a = 0; a < ncolors; a++) + if (!strcmp(colorTable[a].string, buf)) + break; + if (a == ncolors) { /* no color matches */ + XpmFree(iptr2); + return (XpmFileInvalid); + } + *iptr = a; + } + } + } + } + break; + } + *pixels = iptr2; + return (XpmSuccess); +} + +static int +ParseExtensions(xpmData *data, XpmExtension **extensions, unsigned int *nextensions) +{ + XpmExtension *exts = NULL, *ext; + unsigned int num = 0; + unsigned int nlines, a, l, notstart, notend = 0; + int status; + char *string, *s, *s2, **sp; + + xpmNextString(data); + exts = (XpmExtension *) XpmMalloc(sizeof(XpmExtension)); + /* get the whole string */ + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + XpmFree(exts); + return (status); + } + /* look for the key word XPMEXT, skip lines before this */ + while ((notstart = strncmp("XPMEXT", string, 6)) + && (notend = strncmp("XPMENDEXT", string, 9))) { + XpmFree(string); + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + XpmFree(exts); + return (status); + } + } + if (!notstart) + notend = strncmp("XPMENDEXT", string, 9); + while (!notstart && notend) { + /* there starts an extension */ + ext = (XpmExtension *) + XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); + if (!ext) { + XpmFree(string); + XpmFreeExtensions(exts, num); + return (XpmNoMemory); + } + exts = ext; + ext += num; + /* skip whitespace and store its name */ + s2 = s = string + 6; + while (isspace(*s2)) + s2++; + a = s2 - s; + ext->name = (char *) XpmMalloc(l - a - 6); + if (!ext->name) { + XpmFree(string); + ext->lines = NULL; + ext->nlines = 0; + XpmFreeExtensions(exts, num + 1); + return (XpmNoMemory); + } + strncpy(ext->name, s + a, l - a - 6); + XpmFree(string); + /* now store the related lines */ + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + ext->lines = NULL; + ext->nlines = 0; + XpmFreeExtensions(exts, num + 1); + return (status); + } + ext->lines = (char **) XpmMalloc(sizeof(char *)); + nlines = 0; + while ((notstart = strncmp("XPMEXT", string, 6)) + && (notend = strncmp("XPMENDEXT", string, 9))) { + sp = (char **) + XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); + if (!sp) { + XpmFree(string); + ext->nlines = nlines; + XpmFreeExtensions(exts, num + 1); + return (XpmNoMemory); + } + ext->lines = sp; + ext->lines[nlines] = string; + nlines++; + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + ext->nlines = nlines; + XpmFreeExtensions(exts, num + 1); + return (status); + } + } + if (!nlines) { + XpmFree(ext->lines); + ext->lines = NULL; + } + ext->nlines = nlines; + num++; + } + if (!num) { + XpmFree(string); + XpmFree(exts); + exts = NULL; + } else if (!notend) + XpmFree(string); + *nextensions = num; + *extensions = exts; + return (XpmSuccess); +} diff --git a/src/xpm/rdftodat.c b/src/xpm/rdftodat.c new file mode 100644 index 0000000000..28c81ae688 --- /dev/null +++ b/src/xpm/rdftodat.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmRdFToData.c: * +* * +* XPM library * +* Parse an XPM file and create an array of strings corresponding to it. * +* * +* Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com * +\*****************************************************************************/ + +#include "xpm34p.h" + +int +XpmReadFileToData(char *filename, char ***data_return) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + info.valuemask = XpmReturnComments | XpmReturnExtensions; + + /* + * initialize return value + */ + if (data_return) + *data_return = NULL; + + ErrorStatus = XpmReadFileToXpmImage(filename, &image, &info); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + ErrorStatus = + XpmCreateDataFromXpmImage(data_return, &image, &info); + + XpmFreeXpmImage(&image); + XpmFreeXpmInfo(&info); + + return (ErrorStatus); +} diff --git a/src/xpm/rdftoi.c b/src/xpm/rdftoi.c new file mode 100644 index 0000000000..d5aea86da9 --- /dev/null +++ b/src/xpm/rdftoi.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmRdFToI.c: * +* * +* XPM library * +* Parse an XPM file and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" + +int +XpmReadFileToImage(Display *display, char *filename, + XImage **image_return, XImage **shapeimage_return, XpmAttributes *attributes) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + /* create an XpmImage from the file */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = XpmReadFileToXpmImage(filename, &image, &info); + } else + ErrorStatus = XpmReadFileToXpmImage(filename, &image, NULL); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the related ximages */ + ErrorStatus = XpmCreateImageFromXpmImage(display, &image, + image_return, shapeimage_return, + attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmReadFileToXpmImage(char *filename, XpmImage *image, XpmInfo *info) +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open file to read */ + if ((ErrorStatus = xpmReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/rdftop.c b/src/xpm/rdftop.c new file mode 100644 index 0000000000..e1c558f4ba --- /dev/null +++ b/src/xpm/rdftop.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmRdFToP.c: * +* * +* XPM library * +* Parse an XPM file and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifndef FOR_MSW + +#include "xpm34p.h" + +int +XpmReadFileToPixmap(Display *display, Drawable d, char *filename, Pixmap *pixmap_return, + Pixmap *shapemask_return, XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the images */ + ErrorStatus = XpmReadFileToImage(display, filename, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? &shapeimage : NULL), + attributes); + + if (ErrorStatus < 0) /* fatal error */ + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} +#endif diff --git a/src/xpm/readme b/src/xpm/readme new file mode 100644 index 0000000000..a82660fb11 --- /dev/null +++ b/src/xpm/readme @@ -0,0 +1,192 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + + + XPM Version 3 + +WHAT IS XPM? +============ + +XPM (X PixMap) is a format for storing/retrieving X pixmaps to/from files. + +Here is provided a library containing a set of four functions, similar to the +X bitmap functions as defined in the Xlib: XpmCreatePixmapFromData, +XpmCreateDataFromPixmap, XpmReadFileToPixmap and XpmWriteFileFromPixmap for +respectively including, storing, reading and writing this format, plus four +other: XpmCreateImageFromData, XpmCreateDataFromImage, XpmReadFileToImage and +XpmWriteFileFromImage for working with images instead of pixmaps. + +This new version provides a C includable format, defaults for different types +of display: monochrome/color/grayscale, hotspot coordinates and symbol names +for colors for overriding default colors when creating the pixmap. It provides +a mechanism for storing information while reading a file which is re-used +while writing. This way comments, default colors and symbol names aren't lost. +It also handles "transparent pixels" by returning a shape mask in addition to +the created pixmap. + +See the XPM Manual for more details. + +HOW TO GET XPM? +=============== + +New xpm updates are announced on the comp.windows.x newsgroup, and on the +"xpm-talk" list. All new "official" xpm releases can be found by ftp on: + + ftp.x.org (18.112.44.100) contrib (Boston, USA) + avahi.inria.fr (192.5.60.47) pub (Sophia Antipolis, France) + + +DOCUMENTATION: +============= + +Old users might read the CHANGES file for a history of changes interesting +the user. + +Read the doc. The documentation is in PostScript format (file doc/xpm.ps) and +has been produced with FrameMaker. The source files are available on request. + + +INSTALLATION: +============ + +To obtain the XPM library, first uncompress and untar the compressed tar file +in an approriate directory. + +Then you can either compile xpm via "imake" or in a stand-alone way. + +WITH IMAKE: + + Imakefiles are provided to build both shared and unshared libraries. + First have a look at the beginning of the lib/Imakefile and see if you + need to do some modification to fit with your system. + You should know how to use imake to build the XPM Makefiles + by executing "xmkmf", then do: + + make Makefiles + make depend (if you want to) + make + + which will build the XPM library and the sxpm application. + Then do: + + make install + make install.man + + which will install the library and the sxpm pregram and man page. + + If it fails, you may edit the Imakefiles to add compilation flags to + suit your machine. + +WITHOUT IMAKE: + + To compile xpm, in the xpm directory you just created, do: + + make -f Makefile.noXtree + + Then to install it, do: + + make -f Makefile.noXtree install + +SXPM: +==== + +In addition to the library the sxpm tool is provided to show XPM file and +convert them from XPM1 or XPM2 to XPM version 3. If you have previously done +'make' or 'make all' you should have it yet, otherwise just do: + + cd sxpm; make + +This application shows you most of the features of XPM and its source can be +used to quickly see how to use the provided functions. + +By executing 'sxpm -help' you will get the usage. + +Executing 'sxpm -plaid' will show a demo of the XpmCreatePixmapFromData +function. The pixmap is created from the static variable plaid defined in the +sxpm.c file. sxpm will end when you press the key 'q' in the created window. + +Executing 'sxpm -plaid -sc lines_in_mix blue' will show the feature of +overriding color symbols giving a colorname, executing 'sxpm -sp lines_in_mix +1' will show overriding giving a pixel value, and executing 'sxpm -plaid -cp +red 0' will show overriding giving a color value. + +Then you should try 'sxpm -plaid -o output' to get an output file using the +XpmWriteFileFromPixmap function. + +You can now try 'sxpm -plaid -o - -nod -rgb /usr/lib/X11/rgb.txt' to directly +get the pixmap printed out on the standard output with colornames instead of +rgb values. + +Then you should try 'sxpm plaid.xpm' to use the XpmReadFileToPixmap function, +and 'cat plaid_mask.xpm|sxpm' to see how "transparent pixels" are handled. + +The XpmCreatePixmapFromData function is on purpose called without any XpmInfos +flag to show the utility of this one. Indeed, compare the color section of the +two files foo and bar obtained from 'sxpm -nod -plaid -o foo' and 'sxpm -nod +plaid.xpm -o bar'. All the default colors and also the comments have been +restored. + +To end look at plaid_ext.xpm and try "sxpm -nod plaid_ext.xpm -v" to see how +extensions are handled. + +Of course, other combinations are allowed and should be tried. Thus, 'sxpm +plaid.xpm -o output -nod' will show you how to convert a file from XPM1 or XPM2 +to a XPM version 3 using sxpm. + +See the manual page for more detail. + +OTHER TOOLS: +=========== + +Several converters dealing with XPM and a pixmap editor can be found in the +xpm-contrib distribution. Also I recommend the use of netpbm to do any kind of +general image operations such as scaling, resizing, dithering, and to convert +from and to any other image format. + +DISCUSSION: +========== + +There is a mailing list to discuss about XPM which is xpm-talk@sophia.inria.fr. +Any request to subscribe should be sent to xpm-talk-request@sophia.inria.fr. + +COPYRIGHT: +========== + + Copyright 1989-94 GROUPE BULL -- + See license conditions in the COPYRIGHT file of the XPM distribution + +Please mail any bug reports or modifications done, comments, suggestions, +requests for updates or patches to port on another machine to: + +lehors@sophia.inria.fr (INTERNET) + +33 (FRANCE) 93.65.77.71 (VOICE PHONE) + +Arnaud Le Hors (SURFACE MAIL) +Bull c/o Inria BP. 109 +2004, Route des lucioles +Sophia Antipolis +06561 Valbonne Cedex +FRANCE diff --git a/src/xpm/readme.msw b/src/xpm/readme.msw new file mode 100644 index 0000000000..6e97bb5989 --- /dev/null +++ b/src/xpm/readme.msw @@ -0,0 +1,83 @@ + +README.MSW hedu@cul-ipn.uni-kiel.de 5/94 + + The XPM library for MS-Windows + +Motivated by the wxWindows library, which is a (freely available) toolkit +for developing multi-platform, graphical applications from the same body +of C++ code,I wanted to have XPM pixmaps for MS-windows. Instead of rewriting +a XPM-parser I managed to port the XPM-library-code to MS-windows. +Thanks to Anaud Le Hors this became a part of the official XPM-library. + +Until now it's only used together with wxWindows. And even there it's more +a kind of beta. But it should be possible to run it as a simple libxpm.a +without wxWindows. + +The key is a transformation of some X types plus some basic X functions. +There is not yet a special MSW-API, so you should know the X types used. + +The following is done in simx.h: + +typedef HDC Display; +typedef COLORREF Pixel; + +typedef struct { + Pixel pixel; + BYTE red, green, blue; +} XColor; + +typedef struct { + HBITMAP bitmap; + unsigned int width; + unsigned int height; + unsigned int depth; +} XImage; + +With these defines and the according functions from simx.c you can call +XPM-functions the way it's done under X windows. It can look like this: + + ErrorStatus=XpmCreateImageFromData(&dc, data, + &ximage,(XImage **)NULL, &xpmAttr); + ms_bitmap = ximage->bitmap; + // releases the malloc,but do not destroy the bitmap + XImageFree(ximage); + +Supported functions are the Xpm*Image* but not the Xpm*Pixmap*. + +DRAWBACKS: +The main drawback is the missing support for Colormaps! There was nothing for +it in wxWindows, so I did not know how to deal with Colormaps. + +The size of the pixmaps is bounded by malloc() (width*height*2 < 64K). + +Close colors do not look that close. But that seems to be the window system. + +Neither a special API for MSW nor a special MSW documentation other than this. +(I can only point you to wxxpm as an example , see below.) + +INSTALLATION: +There is not yet a makefile with it. Simply take all the *.c files +into your project. +!!!You MUST set FOR_MSW on the preprocessor options!!! +(You might uncomment NEED_STRCASECMP in xpm.h if it's in your lib) +This should compile into libxpm.a. Good luck... + +FTP: +wxWindows is currently available from the Artificial Intelligence +Applications Institute (University of Edinburgh) by anonymous FTP. + skye.aiai.ed.ac.uk pub/wxwin/ +or read http://burray.aiai.ed.ac.uk/aiai/aiai.html + +wxxpm, XPM support for wxWindows, the latest version is available at + yoda.cul-ipn.uni-kiel.de pub/wxxpm/ + and maybe in the contrib or tools of wxWindows + +Please contact me if you have suggestions, comments or problems! + +-- + ////|\\\\ \\\\\\ Hermann Dunkel + O O ////// IPN Uni Kiel, Germany + | \\\\\\ Tel: +49 431 / 880 3144 + \___/ ////// E-mail: hedu@cul-ipn.uni-kiel.de + \_/ \\\\\\ X.400 : c=de;a=d400;p=uni-kiel;ou=nw-didaktik;s=dunkel + diff --git a/src/xpm/rgb.c b/src/xpm/rgb.c new file mode 100644 index 0000000000..38b180dd20 --- /dev/null +++ b/src/xpm/rgb.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* rgb.c: * +* * +* XPM library * +* Rgb file utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * Part of this code has been taken from the ppmtoxpm.c file written by Mark + * W. Snitily but has been modified for my special need + */ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:ctype.h" +#include "sys$library:string.h" +#else +#include +#if defined(SYSV) || defined(SVR4) +#include +#else +#include +#endif +#endif + +#ifndef FOR_MSW /* normal part first, MSW part at + * the end, (huge ifdef!) */ +/* + * Read a rgb text file. It stores the rgb values (0->65535) + * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the + * number of entries stored. + */ +int +xpmReadRgbNames(char *rgb_fname, xpmRgbName rgbn[]) +{ + FILE *rgbf; + int i, items, red, green, blue; + char line[512], name[512], *rgbname, *n, *m; + xpmRgbName *rgb; + + /* Open the rgb text file. Abort if error. */ + if ((rgbf = fopen(rgb_fname, "r")) == NULL) + return 0; + + /* Loop reading each line in the file. */ + for (i = 0, rgb = rgbn; fgets(line, sizeof(line), rgbf); i++, rgb++) { + + /* Quit if rgb text file is too large. */ + if (i == MAX_RGBNAMES) { + /* Too many entries in rgb text file, give up here */ + break; + } + /* Read the line. Skip silently if bad. */ + items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); + if (items != 4) { + i--; + continue; + } + + /* + * Make sure rgb values are within 0->255 range. Skip silently if + * bad. + */ + if (red < 0 || red > 0xFF || + green < 0 || green > 0xFF || + blue < 0 || blue > 0xFF) { + i--; + continue; + } + /* Allocate memory for ascii name. If error give up here. */ + if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1))) + break; + + /* Copy string to ascii name and lowercase it. */ + for (n = name, m = rgbname; *n; n++) + *m++ = tolower(*n); + *m = '\0'; + + /* Save the rgb values and ascii name in the array. */ + rgb->r = red * 257; /* 65535/255 = 257 */ + rgb->g = green * 257; + rgb->b = blue * 257; + rgb->name = rgbname; + } + + fclose(rgbf); + + /* Return the number of read rgb names. */ + return i < 0 ? 0 : i; +} + +/* + * Return the color name corresponding to the given rgb values + */ +char * +xpmGetRgbName(xpmRgbName rgbn[], int rgbn_max, int red, int green, int blue) +/* xpmRgbName rgbn[]; */ /* rgb mnemonics from rgb text file */ +/* int rgbn_max; */ /* number of rgb mnemonics in table */ +/* int red, green, blue; */ /* rgb values */ + +{ + int i; + xpmRgbName *rgb; + + /* + * Just perform a dumb linear search over the rgb values of the color + * mnemonics. One could speed things up by sorting the rgb values and + * using a binary search, or building a hash table, etc... + */ + for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++) + if (red == rgb->r && green == rgb->g && blue == rgb->b) + return rgb->name; + + /* if not found return NULL */ + return NULL; +} + +/* + * Free the strings which have been malloc'ed in xpmReadRgbNames + */ +void +xpmFreeRgbNames(xpmRgbName rgbn[], int rgbn_max) +{ + int i; + xpmRgbName *rgb; + + for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++) + XpmFree(rgb->name); +} + +#else /* here comes the MSW part, the + * second part of the huge ifdef */ + +#include "rgbtab.h" /* hard coded rgb.txt table */ + +int +xpmReadRgbNames(char *rgb_fname, xpmRgbName rgbn[]) +{ + /* + * check for consistency??? + * table has to be sorted for calls on strcasecmp + */ + return (numTheRGBRecords); +} + +/* + * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red, + * which has something like #0303 for one color + */ +char * +xpmGetRgbName(xpmRgbName rgbn[], int rgbn_max, int red, int green, int blue) +/* xpmRgbName rgbn[]; */ /* rgb mnemonics from rgb text file + * not used */ +/* int rgbn_max; */ /* not used */ +/* int red, green, blue; */ /* rgb values */ + +{ + int i; + unsigned long rgbVal; + + i = 0; + while (i < numTheRGBRecords) { + rgbVal = theRGBRecords[i].rgb; + if (GetRValue(rgbVal) == red && + GetGValue(rgbVal) == green && + GetBValue(rgbVal) == blue) + return (theRGBRecords[i].name); + i++; + } + return (NULL); +} + +/* used in XParseColor in simx.c */ +int +xpmGetRGBfromName(char *inname, int *r, int *g, int *b) +{ + int left, right, middle; + int cmp; + unsigned long rgbVal; + char *name; + char *grey, *p; + + name = strdup(inname); + + /* + * the table in rgbtab.c has no names with spaces, and no grey, but a + * lot of gray + */ + /* so first extract ' ' */ + while (p = strchr(name, ' ')) { + while (*(p)) { /* till eof of string */ + *p = *(p + 1); /* copy to the left */ + p++; + } + } + /* fold to lower case */ + p = name; + while (*p) { + *p = tolower(*p); + p++; + } + + /* + * substitute Grey with Gray, else rgbtab.h would have more than 100 + * 'duplicate' entries + */ + if (grey = strstr(name, "grey")) + grey[2] = 'a'; + + /* binary search */ + left = 0; + right = numTheRGBRecords - 1; + do { + middle = (left + right) / 2; + cmp = strcasecmp(name, theRGBRecords[middle].name); + if (cmp == 0) { + rgbVal = theRGBRecords[middle].rgb; + *r = GetRValue(rgbVal); + *g = GetGValue(rgbVal); + *b = GetBValue(rgbVal); + free(name); + return (1); + } else if (cmp < 0) { + right = middle - 1; + } else { /* > 0 */ + left = middle + 1; + } + } while (left <= right); + + /* + * I don't like to run in a ColorInvalid error and to see no pixmap at + * all, so simply return a red pixel. Should be wrapped in an #ifdef + * HeDu + */ + + *r = 255; + *g = 0; + *b = 0; /* red error pixel */ + + free(name); + return (1); +} + +void +xpmFreeRgbNames(xpmRgbName rgbn[], int rgbn_max) +{ + /* nothing to do */ +} + +#endif /* MSW part */ diff --git a/src/xpm/rgbtab.h b/src/xpm/rgbtab.h new file mode 100644 index 0000000000..39e8d27c9c --- /dev/null +++ b/src/xpm/rgbtab.h @@ -0,0 +1,292 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* rgbtab.h * +* * +* A hard coded rgb.txt. To keep it short I removed all colornames with * +* trailing numbers, Blue3 etc, except the GrayXX. Sorry Grey-lovers I prefer * +* Gray ;-). But Grey is recognized on lookups, only on save Gray will be * +* used, maybe you want to do some substitue there too. * +* * +* To save memory the RGBs are coded in one long value, as done by the RGB * +* macro. * +* * +* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de) * +\*****************************************************************************/ + + +typedef struct { + char *name; + COLORREF rgb; /* it's unsigned long */ +} rgbRecord; + +/* +#define myRGB(r,g,b) \ + ((unsigned long)r<<16|(unsigned long)g<<8|(unsigned long)b) +*/ +#define myRGB(r,g,b) RGB(r,g,b) /* MSW has this macro */ + + +static rgbRecord theRGBRecords[] = +{ + {"AliceBlue", myRGB(240, 248, 255)}, + {"AntiqueWhite", myRGB(250, 235, 215)}, + {"Aquamarine", myRGB(50, 191, 193)}, + {"Azure", myRGB(240, 255, 255)}, + {"Beige", myRGB(245, 245, 220)}, + {"Bisque", myRGB(255, 228, 196)}, + {"Black", myRGB(0, 0, 0)}, + {"BlanchedAlmond", myRGB(255, 235, 205)}, + {"Blue", myRGB(0, 0, 255)}, + {"BlueViolet", myRGB(138, 43, 226)}, + {"Brown", myRGB(165, 42, 42)}, + {"burlywood", myRGB(222, 184, 135)}, + {"CadetBlue", myRGB(95, 146, 158)}, + {"chartreuse", myRGB(127, 255, 0)}, + {"chocolate", myRGB(210, 105, 30)}, + {"Coral", myRGB(255, 114, 86)}, + {"CornflowerBlue", myRGB(34, 34, 152)}, + {"cornsilk", myRGB(255, 248, 220)}, + {"Cyan", myRGB(0, 255, 255)}, + {"DarkGoldenrod", myRGB(184, 134, 11)}, + {"DarkGreen", myRGB(0, 86, 45)}, + {"DarkKhaki", myRGB(189, 183, 107)}, + {"DarkOliveGreen", myRGB(85, 86, 47)}, + {"DarkOrange", myRGB(255, 140, 0)}, + {"DarkOrchid", myRGB(139, 32, 139)}, + {"DarkSalmon", myRGB(233, 150, 122)}, + {"DarkSeaGreen", myRGB(143, 188, 143)}, + {"DarkSlateBlue", myRGB(56, 75, 102)}, + {"DarkSlateGray", myRGB(47, 79, 79)}, + {"DarkTurquoise", myRGB(0, 166, 166)}, + {"DarkViolet", myRGB(148, 0, 211)}, + {"DeepPink", myRGB(255, 20, 147)}, + {"DeepSkyBlue", myRGB(0, 191, 255)}, + {"DimGray", myRGB(84, 84, 84)}, + {"DodgerBlue", myRGB(30, 144, 255)}, + {"Firebrick", myRGB(142, 35, 35)}, + {"FloralWhite", myRGB(255, 250, 240)}, + {"ForestGreen", myRGB(80, 159, 105)}, + {"gainsboro", myRGB(220, 220, 220)}, + {"GhostWhite", myRGB(248, 248, 255)}, + {"Gold", myRGB(218, 170, 0)}, + {"Goldenrod", myRGB(239, 223, 132)}, + {"Gray", myRGB(126, 126, 126)}, + {"Gray0", myRGB(0, 0, 0)}, + {"Gray1", myRGB(3, 3, 3)}, + {"Gray10", myRGB(26, 26, 26)}, + {"Gray100", myRGB(255, 255, 255)}, + {"Gray11", myRGB(28, 28, 28)}, + {"Gray12", myRGB(31, 31, 31)}, + {"Gray13", myRGB(33, 33, 33)}, + {"Gray14", myRGB(36, 36, 36)}, + {"Gray15", myRGB(38, 38, 38)}, + {"Gray16", myRGB(41, 41, 41)}, + {"Gray17", myRGB(43, 43, 43)}, + {"Gray18", myRGB(46, 46, 46)}, + {"Gray19", myRGB(48, 48, 48)}, + {"Gray2", myRGB(5, 5, 5)}, + {"Gray20", myRGB(51, 51, 51)}, + {"Gray21", myRGB(54, 54, 54)}, + {"Gray22", myRGB(56, 56, 56)}, + {"Gray23", myRGB(59, 59, 59)}, + {"Gray24", myRGB(61, 61, 61)}, + {"Gray25", myRGB(64, 64, 64)}, + {"Gray26", myRGB(66, 66, 66)}, + {"Gray27", myRGB(69, 69, 69)}, + {"Gray28", myRGB(71, 71, 71)}, + {"Gray29", myRGB(74, 74, 74)}, + {"Gray3", myRGB(8, 8, 8)}, + {"Gray30", myRGB(77, 77, 77)}, + {"Gray31", myRGB(79, 79, 79)}, + {"Gray32", myRGB(82, 82, 82)}, + {"Gray33", myRGB(84, 84, 84)}, + {"Gray34", myRGB(87, 87, 87)}, + {"Gray35", myRGB(89, 89, 89)}, + {"Gray36", myRGB(92, 92, 92)}, + {"Gray37", myRGB(94, 94, 94)}, + {"Gray38", myRGB(97, 97, 97)}, + {"Gray39", myRGB(99, 99, 99)}, + {"Gray4", myRGB(10, 10, 10)}, + {"Gray40", myRGB(102, 102, 102)}, + {"Gray41", myRGB(105, 105, 105)}, + {"Gray42", myRGB(107, 107, 107)}, + {"Gray43", myRGB(110, 110, 110)}, + {"Gray44", myRGB(112, 112, 112)}, + {"Gray45", myRGB(115, 115, 115)}, + {"Gray46", myRGB(117, 117, 117)}, + {"Gray47", myRGB(120, 120, 120)}, + {"Gray48", myRGB(122, 122, 122)}, + {"Gray49", myRGB(125, 125, 125)}, + {"Gray5", myRGB(13, 13, 13)}, + {"Gray50", myRGB(127, 127, 127)}, + {"Gray51", myRGB(130, 130, 130)}, + {"Gray52", myRGB(133, 133, 133)}, + {"Gray53", myRGB(135, 135, 135)}, + {"Gray54", myRGB(138, 138, 138)}, + {"Gray55", myRGB(140, 140, 140)}, + {"Gray56", myRGB(143, 143, 143)}, + {"Gray57", myRGB(145, 145, 145)}, + {"Gray58", myRGB(148, 148, 148)}, + {"Gray59", myRGB(150, 150, 150)}, + {"Gray6", myRGB(15, 15, 15)}, + {"Gray60", myRGB(153, 153, 153)}, + {"Gray61", myRGB(156, 156, 156)}, + {"Gray62", myRGB(158, 158, 158)}, + {"Gray63", myRGB(161, 161, 161)}, + {"Gray64", myRGB(163, 163, 163)}, + {"Gray65", myRGB(166, 166, 166)}, + {"Gray66", myRGB(168, 168, 168)}, + {"Gray67", myRGB(171, 171, 171)}, + {"Gray68", myRGB(173, 173, 173)}, + {"Gray69", myRGB(176, 176, 176)}, + {"Gray7", myRGB(18, 18, 18)}, + {"Gray70", myRGB(179, 179, 179)}, + {"Gray71", myRGB(181, 181, 181)}, + {"Gray72", myRGB(184, 184, 184)}, + {"Gray73", myRGB(186, 186, 186)}, + {"Gray74", myRGB(189, 189, 189)}, + {"Gray75", myRGB(191, 191, 191)}, + {"Gray76", myRGB(194, 194, 194)}, + {"Gray77", myRGB(196, 196, 196)}, + {"Gray78", myRGB(199, 199, 199)}, + {"Gray79", myRGB(201, 201, 201)}, + {"Gray8", myRGB(20, 20, 20)}, + {"Gray80", myRGB(204, 204, 204)}, + {"Gray81", myRGB(207, 207, 207)}, + {"Gray82", myRGB(209, 209, 209)}, + {"Gray83", myRGB(212, 212, 212)}, + {"Gray84", myRGB(214, 214, 214)}, + {"Gray85", myRGB(217, 217, 217)}, + {"Gray86", myRGB(219, 219, 219)}, + {"Gray87", myRGB(222, 222, 222)}, + {"Gray88", myRGB(224, 224, 224)}, + {"Gray89", myRGB(227, 227, 227)}, + {"Gray9", myRGB(23, 23, 23)}, + {"Gray90", myRGB(229, 229, 229)}, + {"Gray91", myRGB(232, 232, 232)}, + {"Gray92", myRGB(235, 235, 235)}, + {"Gray93", myRGB(237, 237, 237)}, + {"Gray94", myRGB(240, 240, 240)}, + {"Gray95", myRGB(242, 242, 242)}, + {"Gray96", myRGB(245, 245, 245)}, + {"Gray97", myRGB(247, 247, 247)}, + {"Gray98", myRGB(250, 250, 250)}, + {"Gray99", myRGB(252, 252, 252)}, + {"Green", myRGB(0, 255, 0)}, + {"GreenYellow", myRGB(173, 255, 47)}, + {"honeydew", myRGB(240, 255, 240)}, + {"HotPink", myRGB(255, 105, 180)}, + {"IndianRed", myRGB(107, 57, 57)}, + {"ivory", myRGB(255, 255, 240)}, + {"Khaki", myRGB(179, 179, 126)}, + {"lavender", myRGB(230, 230, 250)}, + {"LavenderBlush", myRGB(255, 240, 245)}, + {"LawnGreen", myRGB(124, 252, 0)}, + {"LemonChiffon", myRGB(255, 250, 205)}, + {"LightBlue", myRGB(176, 226, 255)}, + {"LightCoral", myRGB(240, 128, 128)}, + {"LightCyan", myRGB(224, 255, 255)}, + {"LightGoldenrod", myRGB(238, 221, 130)}, + {"LightGoldenrodYellow", myRGB(250, 250, 210)}, + {"LightGray", myRGB(168, 168, 168)}, + {"LightPink", myRGB(255, 182, 193)}, + {"LightSalmon", myRGB(255, 160, 122)}, + {"LightSeaGreen", myRGB(32, 178, 170)}, + {"LightSkyBlue", myRGB(135, 206, 250)}, + {"LightSlateBlue", myRGB(132, 112, 255)}, + {"LightSlateGray", myRGB(119, 136, 153)}, + {"LightSteelBlue", myRGB(124, 152, 211)}, + {"LightYellow", myRGB(255, 255, 224)}, + {"LimeGreen", myRGB(0, 175, 20)}, + {"linen", myRGB(250, 240, 230)}, + {"Magenta", myRGB(255, 0, 255)}, + {"Maroon", myRGB(143, 0, 82)}, + {"MediumAquamarine", myRGB(0, 147, 143)}, + {"MediumBlue", myRGB(50, 50, 204)}, + {"MediumForestGreen", myRGB(50, 129, 75)}, + {"MediumGoldenrod", myRGB(209, 193, 102)}, + {"MediumOrchid", myRGB(189, 82, 189)}, + {"MediumPurple", myRGB(147, 112, 219)}, + {"MediumSeaGreen", myRGB(52, 119, 102)}, + {"MediumSlateBlue", myRGB(106, 106, 141)}, + {"MediumSpringGreen", myRGB(35, 142, 35)}, + {"MediumTurquoise", myRGB(0, 210, 210)}, + {"MediumVioletRed", myRGB(213, 32, 121)}, + {"MidnightBlue", myRGB(47, 47, 100)}, + {"MintCream", myRGB(245, 255, 250)}, + {"MistyRose", myRGB(255, 228, 225)}, + {"moccasin", myRGB(255, 228, 181)}, + {"NavajoWhite", myRGB(255, 222, 173)}, + {"Navy", myRGB(35, 35, 117)}, + {"NavyBlue", myRGB(35, 35, 117)}, + {"OldLace", myRGB(253, 245, 230)}, + {"OliveDrab", myRGB(107, 142, 35)}, + {"Orange", myRGB(255, 135, 0)}, + {"OrangeRed", myRGB(255, 69, 0)}, + {"Orchid", myRGB(239, 132, 239)}, + {"PaleGoldenrod", myRGB(238, 232, 170)}, + {"PaleGreen", myRGB(115, 222, 120)}, + {"PaleTurquoise", myRGB(175, 238, 238)}, + {"PaleVioletRed", myRGB(219, 112, 147)}, + {"PapayaWhip", myRGB(255, 239, 213)}, + {"PeachPuff", myRGB(255, 218, 185)}, + {"peru", myRGB(205, 133, 63)}, + {"Pink", myRGB(255, 181, 197)}, + {"Plum", myRGB(197, 72, 155)}, + {"PowderBlue", myRGB(176, 224, 230)}, + {"purple", myRGB(160, 32, 240)}, + {"Red", myRGB(255, 0, 0)}, + {"RosyBrown", myRGB(188, 143, 143)}, + {"RoyalBlue", myRGB(65, 105, 225)}, + {"SaddleBrown", myRGB(139, 69, 19)}, + {"Salmon", myRGB(233, 150, 122)}, + {"SandyBrown", myRGB(244, 164, 96)}, + {"SeaGreen", myRGB(82, 149, 132)}, + {"seashell", myRGB(255, 245, 238)}, + {"Sienna", myRGB(150, 82, 45)}, + {"SkyBlue", myRGB(114, 159, 255)}, + {"SlateBlue", myRGB(126, 136, 171)}, + {"SlateGray", myRGB(112, 128, 144)}, + {"snow", myRGB(255, 250, 250)}, + {"SpringGreen", myRGB(65, 172, 65)}, + {"SteelBlue", myRGB(84, 112, 170)}, + {"Tan", myRGB(222, 184, 135)}, + {"Thistle", myRGB(216, 191, 216)}, + {"tomato", myRGB(255, 99, 71)}, + {"Transparent", myRGB(0, 0, 1)}, + {"Turquoise", myRGB(25, 204, 223)}, + {"Violet", myRGB(156, 62, 206)}, + {"VioletRed", myRGB(243, 62, 150)}, + {"Wheat", myRGB(245, 222, 179)}, + {"White", myRGB(255, 255, 255)}, + {"WhiteSmoke", myRGB(245, 245, 245)}, + {"Yellow", myRGB(255, 255, 0)}, + {"YellowGreen", myRGB(50, 216, 56)}, + NULL +}; + +static int numTheRGBRecords = 234; diff --git a/src/xpm/scan.c b/src/xpm/scan.c new file mode 100644 index 0000000000..fb16180fd8 --- /dev/null +++ b/src/xpm/scan.c @@ -0,0 +1,843 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* scan.c: * +* * +* XPM library * +* Scanning utility for XPM file format * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#include "xpm34p.h" + +#define MAXPRINTABLE 92 /* number of printable ascii chars + * minus \ and " for string compat + * and ? to avoid ANSI trigraphs. */ + +static char *printable = +" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ +ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; + +/* + * printable begin with a space, so in most case, due to my algorithm, when + * the number of different colors is less than MAXPRINTABLE, it will give a + * char follow by "nothing" (a space) in the readable xpm file + */ + + +typedef struct { + Pixel *pixels; + unsigned int *pixelindex; + unsigned int size; + unsigned int ncolors; + unsigned int mask_pixel; /* whether there is or not */ +} PixelsMap; + +LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap, + unsigned int *index_return)); + +LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap, + unsigned int *index_return)); + +#ifndef FOR_MSW +LFUNC(GetImagePixels, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap, + int (*storeFunc) (Pixel,PixelsMap*, + unsigned int*))); + +/* + int (*storeFunc) ())); +*/ + +#else /* ndef FOR_MSW */ +LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); +#endif +LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp, + XpmAttributes *attributes)); + +LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors, + Pixel *pixels, unsigned int mask, + unsigned int cpp, XpmAttributes *attributes)); + +/* + * This function stores the given pixel in the given arrays which are grown + * if not large enough. + */ +static int +storePixel(Pixel pixel, PixelsMap *pmap, unsigned int *index_return) +{ + unsigned int i; + Pixel *p; + unsigned int ncolors; + + if (*index_return) { /* this is a transparent pixel! */ + *index_return = 0; + return 0; + } + ncolors = pmap->ncolors; + p = pmap->pixels + pmap->mask_pixel; + for (i = pmap->mask_pixel; i < ncolors; i++, p++) + if (*p == pixel) + break; + if (i == ncolors) { + if (ncolors >= pmap->size) { + pmap->size *= 2; + p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size); + if (!p) + return (1); + pmap->pixels = p; + + } + (pmap->pixels)[ncolors] = pixel; + pmap->ncolors++; + } + *index_return = i; + return 0; +} + +static int +storeMaskPixel(Pixel pixel, PixelsMap *pmap, unsigned int *index_return) +{ + if (!pixel) { + if (!pmap->ncolors) { + pmap->ncolors = 1; + (pmap->pixels)[0] = 0; + pmap->mask_pixel = 1; + } + *index_return = 1; + } else + *index_return = 0; + return 0; +} + +/* function call in case of error, frees only locally allocated variables */ +#undef RETURN +#define RETURN(status) \ +{ \ + if (pmap.pixelindex) XpmFree(pmap.pixelindex); \ + if (pmap.pixels) XpmFree(pmap.pixels); \ + if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \ + return(status); \ +} + +/* + * This function scans the given image and stores the found informations in + * the given XpmImage structure. + */ +int +XpmCreateXpmImageFromImage(Display *display, XImage *image, XImage *shapeimage, + XpmImage *xpmimage, XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + unsigned int cpp; + + /* variables to return */ + PixelsMap pmap; + XpmColor *colorTable = NULL; + int ErrorStatus; + + /* calculation variables */ + unsigned int width = 0; + unsigned int height = 0; + unsigned int cppm; /* minimum chars per pixel */ + unsigned int c; + unsigned int offset; + + /* initialize pmap */ + pmap.pixels = NULL; + pmap.pixelindex = NULL; + pmap.size = 256; /* should be enough most of the time */ + pmap.ncolors = 0; + pmap.mask_pixel = 0; + + /* + * get geometry + */ + if (image) { + width = image->width; + height = image->height; + } else if (shapeimage) { + width = shapeimage->width; + height = shapeimage->height; + } + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && (attributes->valuemask & XpmCharsPerPixel +/* 3.2 backward compatibility code */ + || attributes->valuemask & XpmInfos)) +/* end 3.2 bc */ + cpp = attributes->cpp; + else + cpp = 0; + + pmap.pixelindex = + (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int)); + if (!pmap.pixelindex) + RETURN(XpmNoMemory); + + pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size); + if (!pmap.pixels) + RETURN(XpmNoMemory); + + /* + * scan shape mask if any + */ + if (shapeimage) { +#ifndef FOR_MSW + ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap, + storeMaskPixel); +#else + ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height, + &pmap); +#endif + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * scan the image data + * + * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized + * functions, otherwise use slower but sure general one. + * + */ + + if (image) { +#ifndef FOR_MSW + if (image->depth == 1) + ErrorStatus = GetImagePixels1(image, width, height, &pmap, + storePixel); + else if (image->bits_per_pixel == 8) + ErrorStatus = GetImagePixels8(image, width, height, &pmap); + else if (image->bits_per_pixel == 16) + ErrorStatus = GetImagePixels16(image, width, height, &pmap); + else if (image->bits_per_pixel == 32) + ErrorStatus = GetImagePixels32(image, width, height, &pmap); + else + ErrorStatus = GetImagePixels(image, width, height, &pmap); +#else /* FOR_MSW */ + ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap); +#endif + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * get rgb values and a string of char, and possibly a name for each + * color + */ + + colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor)); + if (!colorTable) + RETURN(XpmNoMemory); + + /* compute the minimal cpp */ + for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++) + c *= MAXPRINTABLE; + if (cpp < cppm) + cpp = cppm; + + if (pmap.mask_pixel) { + ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + offset = 1; + } else + offset = 0; + + ErrorStatus = ScanOtherColors(display, colorTable + offset, + pmap.ncolors - offset, pmap.pixels + offset, + pmap.mask_pixel, cpp, attributes); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store found informations in the XpmImage structure + */ + xpmimage->width = width; + xpmimage->height = height; + xpmimage->cpp = cpp; + xpmimage->ncolors = pmap.ncolors; + xpmimage->colorTable = colorTable; + xpmimage->data = pmap.pixelindex; + + XpmFree(pmap.pixels); + return (XpmSuccess); +} + +static int +ScanTransparentColor(XpmColor *color, unsigned int cpp, XpmAttributes *attributes) +{ + char *s; + unsigned int a, b, c; + + /* first get a character string */ + a = 0; + if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) + return (XpmNoMemory); + *s++ = printable[c = a % MAXPRINTABLE]; + for (b = 1; b < cpp; b++, s++) + *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE]; + *s = '\0'; + + /* then retreive related info from the attributes if any */ + if (attributes && attributes->mask_pixel != XpmUndefPixel && ( +/* 3.2 backward compatibility code */ + attributes->valuemask & XpmInfos || +/* end 3.2 bc */ + attributes->valuemask & XpmColorTable)) { + + unsigned int key; + char **defaults = (char **) color; + char **mask_defaults; + +/* 3.2 backward compatibility code */ + if (attributes->valuemask & XpmInfos) + mask_defaults = (char **) + ((XpmColor **) attributes->colorTable)[attributes->mask_pixel]; + else +/* end 3.2 bc */ + mask_defaults = (char **) ( + attributes->colorTable + attributes->mask_pixel); + for (key = 1; key <= NKEYS; key++) { + if (s = mask_defaults[key]) { + defaults[key] = (char *) strdup(s); + if (!defaults[key]) + return (XpmNoMemory); + } + } + } else { + color->c_color = (char *) strdup(TRANSPARENT_COLOR); + if (!color->c_color) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +static int +ScanOtherColors(Display *display, XpmColor *colors, int ncolors, Pixel *pixels, + unsigned int mask, unsigned int cpp, XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + Colormap colormap; + char *rgb_fname; + +#ifndef FOR_MSW + xpmRgbName rgbn[MAX_RGBNAMES]; +#else + xpmRgbName *rgbn = NULL; +#endif + int rgbn_max = 0; + unsigned int i, j, c, i2; + XpmColor *color; + XColor *xcolors = NULL, *xcolor; + char *colorname, *s; + XpmColor *colorTable, **oldColorTable = NULL; + unsigned int ancolors = 0; + Pixel *apixels; + unsigned int mask_pixel; + int found; + + /* retrieve information from the XpmAttributes */ + if (attributes && (attributes->valuemask & XpmColormap)) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + if (attributes && (attributes->valuemask & XpmRgbFilename)) + rgb_fname = attributes->rgb_fname; + else + rgb_fname = NULL; + + /* first get character strings and rgb values */ + xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors); + if (!xcolors) + return (XpmNoMemory); + + for (i = 0, i2 = (mask ? i + 1 : i), color = colors, xcolor = xcolors; + i < ncolors; i++, i2++, color++, xcolor++, pixels++) { + + if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) { + XpmFree(xcolors); + return (XpmNoMemory); + } + *s++ = printable[c = i2 % MAXPRINTABLE]; + for (j = 1; j < cpp; j++, s++) + *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE]; + *s = '\0'; + + xcolor->pixel = *pixels; + } +#ifdef wx_msw + XQueryColors(display, (Colormap *)colormap, xcolors, ncolors); +#else + XQueryColors(display, (Colormap)colormap, xcolors, ncolors); +#endif + +#ifndef FOR_MSW + /* read the rgb file if any was specified */ + if (rgb_fname) + rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn); +#else + /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */ + rgbn_max = xpmReadRgbNames(NULL, NULL); +#endif + + if (attributes && attributes->valuemask & XpmColorTable) { + colorTable = attributes->colorTable; + ancolors = attributes->ncolors; + apixels = attributes->pixels; + mask_pixel = attributes->mask_pixel; + } +/* 3.2 backward compatibility code */ + else if (attributes && attributes->valuemask & XpmInfos) { + oldColorTable = (XpmColor **) attributes->colorTable; + ancolors = attributes->ncolors; + apixels = attributes->pixels; + mask_pixel = attributes->mask_pixel; + } +/* end 3.2 bc */ + + for (i = 0, color = colors, xcolor = xcolors; i < ncolors; + i++, color++, xcolor++) { + + /* look for related info from the attributes if any */ + found = False; + if (ancolors) { + unsigned int offset = 0; + + for (j = 0; j < ancolors; j++) { + if (j == mask_pixel) { + offset = 1; + continue; + } + if (apixels[j - offset] == xcolor->pixel) + break; + } + if (j != ancolors) { + unsigned int key; + char **defaults = (char **) color; + char **adefaults; + +/* 3.2 backward compatibility code */ + if (oldColorTable) + adefaults = (char **) oldColorTable[j]; + else +/* end 3.2 bc */ + adefaults = (char **) (colorTable + j); + + found = True; + for (key = 1; key <= NKEYS; key++) { + if (s = adefaults[key]) + defaults[key] = (char *) strdup(s); + } + } + } + if (!found) { + /* if nothing found look for a color name */ + colorname = NULL; + if (rgbn_max) + colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red, + xcolor->green, xcolor->blue); + if (colorname) + color->c_color = (char *) strdup(colorname); + else { + /* at last store the rgb value */ + char buf[BUFSIZ]; +#ifndef FOR_MSW + sprintf(buf, "#%04X%04X%04X", + xcolor->red, xcolor->green, xcolor->blue); +#else + sprintf(buf, "#%02x%02x%02x", + xcolor->red, xcolor->green, xcolor->blue); +#endif + color->c_color = (char *) strdup(buf); + } + if (!color->c_color) { + XpmFree(xcolors); + xpmFreeRgbNames(rgbn, rgbn_max); + return (XpmNoMemory); + } + } + } + + XpmFree(xcolors); + xpmFreeRgbNames(rgbn, rgbn_max); + return (XpmSuccess); +} + +#ifndef FOR_MSW +/* + * The functions below are written from X11R5 MIT's code (XImUtil.c) + * + * The idea is to have faster functions than the standard XGetPixel function + * to scan the image data. Indeed we can speed up things by suppressing tests + * performed for each pixel. We do exactly the same tests but at the image + * level. Assuming that we use only ZPixmap images. + */ + +static unsigned long Const low_bits_table[] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff +}; + +/* + * Default method to scan pixels of a Z image data structure. + * The algorithm used is: + * + * copy the source bitmap_unit or Zpixel into temp + * normalize temp if needed + * extract the pixel bits into return value + * + */ + +static int +GetImagePixels(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap) +{ + char *src; + char *dst; + unsigned int *iptr; + char *data; + int x, y, i; + int bits, depth, ibu, ibpp; + unsigned long lbt; + Pixel pixel, px; + + data = image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + ibpp = image->bits_per_pixel; + if (image->depth == 1) { + ibu = image->bitmap_unit; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + src = &data[XYINDEX(x, y, image)]; + dst = (char *) &pixel; + pixel = 0; + for (i = ibu >> 3; --i >= 0;) + *dst++ = *src++; + XYNORMALIZE(&pixel, image); + bits = x % ibu; + pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1; + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + src = &data[ZINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + for (i = (ibpp + 7) >> 3; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, image); + pixel = 0; + for (i = sizeof(unsigned long); --i >= 0;) + pixel = (pixel << 8) | ((unsigned char *) &px)[i]; + if (ibpp == 4) { + if (x & 1) + pixel >>= 4; + else + pixel &= 0xf; + } + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return (XpmSuccess); +} + +/* + * scan pixels of a 32-bits Z image data structure + */ + +#ifndef WORD64 +static unsigned long byteorderpixel = MSBFirst << 24; + +#endif + +static int +GetImagePixels32(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap) +{ + unsigned char *addr; + unsigned char *data; + unsigned int *iptr; + int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; +#ifndef WORD64 + if (*((char *) &byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = *((unsigned long *) addr); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = ((unsigned long) addr[0] << 24 | + (unsigned long) addr[1] << 16 | + (unsigned long) addr[2] << 8 | + addr[4]); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = (addr[0] | + (unsigned long) addr[1] << 8 | + (unsigned long) addr[2] << 16 | + (unsigned long) addr[3] << 24); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +/* + * scan pixels of a 16-bits Z image data structure + */ + +static int +GetImagePixels16(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap) +{ + unsigned char *addr; + unsigned char *data; + unsigned int *iptr; + int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + pixel = addr[0] << 8 | addr[1]; + if (depth != 16) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + pixel = addr[0] | addr[1] << 8; + if (depth != 16) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +/* + * scan pixels of a 8-bits Z image data structure + */ + +static int +GetImagePixels8(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap) +{ + unsigned int *iptr; + unsigned char *data; + int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = data[ZINDEX8(x, y, image)]; + if (depth != 8) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +/* + * scan pixels of a 1-bit depth Z image data structure + */ + +static int +GetImagePixels1(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap, +/* + int (*storeFunc)() +*/ + int (*storeFunc)(Pixel,PixelsMap*,unsigned int*) +) +{ + unsigned int *iptr; + int x, y; + char *data; + Pixel pixel; + + if (image->byte_order != image->bitmap_bit_order) + return (GetImagePixels(image, width, height, pmap)); + else { + data = image->data; + iptr = pmap->pixelindex; + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = (data[ZINDEX1(x, y, image)] & (0x80 >> (x & 7))) + ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = (data[ZINDEX1(x, y, image)] & (1 << (x & 7))) + ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return (XpmSuccess); +} + +#else /* ndef FOR_MSW */ +static int +MSWGetImagePixels(Display *display, XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap) +{ + unsigned int *iptr; + unsigned int x, y; + Pixel pixel; + + iptr = pmap->pixelindex; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++, iptr++) { + /* bitmap must be selected !!! ??? */ + pixel = GetPixel(*display, x, y); + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return (XpmSuccess); +} + +#endif + +#ifndef FOR_MSW +int +XpmCreateXpmImageFromPixmap(Display *display, Pixmap pixmap, Pixmap shapemask, + XpmImage *xpmimage, XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* create the related XpmImage */ + ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage, + xpmimage, attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} + +#endif /* ndef FOR_MSW */ diff --git a/src/xpm/simx.c b/src/xpm/simx.c new file mode 100644 index 0000000000..78bf77b0fc --- /dev/null +++ b/src/xpm/simx.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* simx.c: 0.1a * +* * +* This emulates some Xlib functionality for MSW. It's not a general solution, * +* it is close related to XPM-lib. It is only intended to satisfy what is need * +* there. Thus allowing to read XPM files under MS windows. * +* * +* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de) * +\*****************************************************************************/ + +#include "xpm34.h" + +#ifdef FOR_MSW + +#include "xpm34p.h" /* for XpmMalloc */ + +/* + * On DOS size_t is only 2 bytes, thus malloc(size_t s) can only malloc + * 64K. BUT an expression data=malloc(width*height) may result in an + * overflow. So this function takes a long as input, and returns NULL if the + * request is larger than 64K, is size_t is only 2 bytes. + * + * This requires casts like XpmMalloc( (long)width*(long(height)), else it + * might have no effect at all. + */ + +void * +boundCheckingMalloc(long s) +{ + if (sizeof(size_t) == sizeof(long)) { /* same size, just do it */ + return (malloc((size_t) s)); + } else { + if (sizeof(size_t) == 2) { + if (s > 0xFFFF) + return (NULL); /* to large, size_t with 2 bytes + * only allows 16 bits */ + else + return (malloc((size_t) s)); + } else { /* it's not a long, not 2 bytes, + * what is it ??? */ + return (malloc((size_t) s)); + } + } +} +void * +boundCheckingCalloc(long num, long s) +{ + if (sizeof(size_t) == sizeof(long)) { /* same size, just do it */ + return (calloc((size_t) num, (size_t) s)); + } else { + if (sizeof(size_t) == 2) { + if (s > 0xFFFF || num * s > 0xFFFF) + return (NULL); /* to large, size_t with 2 bytes + * only allows 16 bits */ + else + return (calloc((size_t) num, (size_t) s)); + } else { /* it's not a long, not 2 bytes, + * what is it ??? */ + return (calloc((size_t) num, (size_t) s)); + } + } +} +void * +boundCheckingRealloc(void *p, long s) +{ + if (sizeof(size_t) == sizeof(long)) { /* same size, just do it */ + return (realloc(p, (size_t) s)); + } else { + if (sizeof(size_t) == 2) { + if (s > 0xFFFF) + return (NULL); /* to large, size_t with 2 bytes + * only allows 16 bits */ + else + return (realloc(p, (size_t) s)); + } else { /* it's not a long, not 2 bytes, + * what is it ??? */ + return (realloc(p, (size_t) s)); + } + } +} + +/* static Visual theVisual = { 0 }; */ +Visual * +XDefaultVisual(Display *display, Screen *screen) +{ + return (NULL); /* struct could contain info about + * MONO, GRAY, COLOR */ +} + +Screen * +XDefaultScreen(Display *d) +{ + return (NULL); +} + +/* I get only 1 plane but 8 bits per pixel, + so I think BITSPIXEL should be depth */ +int +XDefaultDepth(Display *display, Screen *screen) +{ + int d, b; + + b = GetDeviceCaps(*display, BITSPIXEL); + d = GetDeviceCaps(*display, PLANES); + return (b); +} + +Colormap * +XDefaultColormap(Display *display, Screen *screen) +{ + return (NULL); +} + +/* convert hex color names, + wrong digits (not a-f,A-F,0-9) are treated as zero */ +static int +hexCharToInt(char c) +{ + int r; + + if (c >= '0' && c <= '9') + r = c - '0'; + else if (c >= 'a' && c <= 'f') + r = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + r = c - 'A' + 10; + else + r = 0; + + return (r); +} + +static int +rgbFromHex(char *hex, int *r, int *g, int *b) +{ + int len; + + if (hex == NULL || hex[0] != '#') + return (0); + + len = strlen(hex); + if (len == 3 + 1) { + *r = hexCharToInt(hex[1]); + *g = hexCharToInt(hex[2]); + *b = hexCharToInt(hex[3]); + } else if (len == 6 + 1) { + *r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]); + *g = hexCharToInt(hex[3]) * 16 + hexCharToInt(hex[4]); + *b = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]); + } else if (len == 12 + 1) { + /* it's like c #32329999CCCC */ + /* so for now only take two digits */ + *r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]); + *g = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]); + *b = hexCharToInt(hex[9]) * 16 + hexCharToInt(hex[10]); + } else + return (0); + + return (1); +} + +/* Color related functions */ +int +XParseColor(Display *d, Colormap *cmap, char *name, XColor *color) +{ + int r, g, b; /* only 8 bit values used */ + int okay; + +/* TODO: use colormap via PALETTE */ + /* parse name either in table or #RRGGBB #RGB */ + if (name == NULL) + return (0); + + if (name[0] == '#') { /* a hex string */ + okay = rgbFromHex(name, &r, &g, &b); + } else { + okay = xpmGetRGBfromName(name, &r, &g, &b); + } + + if (okay) { + color->pixel = RGB(r, g, b); + color->red = (BYTE) r; + color->green = (BYTE) g; + color->blue = (BYTE) b; + return (1); + } else + return (0); /* --> ColorError */ +} + + +int +XAllocColor(Display *d, Colormap *cmap, XColor *color) +{ +/* colormap not used yet so color->pixel is the real COLORREF (RBG) and not an + index in some colormap as in X */ + return (1); +} +void +XQueryColors(Display *display, Colormap *colormap, + XColor *xcolors, int ncolors) +{ +/* under X this fills the rgb values to given .pixel */ +/* since there no colormap use FOR_MSW (not yet!!), rgb is plain encoded */ + XColor *xc = xcolors; + int i; + + for (i = 0; i < ncolors; i++, xc++) { + xc->red = GetRValue(xc->pixel); + xc->green = GetGValue(xc->pixel); + xc->blue = GetBValue(xc->pixel); + } + return; +} +int +XFreeColors(Display *d, Colormap cmap, + unsigned long pixels[], int npixels, unsigned long planes) +{ + /* no colormap yet */ + return (0); /* correct ??? */ +} + +/* XImage functions */ +XImage * +XCreateImage(Display *d, Visual *v, + int depth, int format, + int x, int y, int width, int height, + int pad, int foo) +{ + XImage *img = (XImage *) XpmMalloc(sizeof(XImage)); + + if (img) { + /* *img = CreateCompatibleBitmap(*d, width, height); */ + img->bitmap = CreateBitmap(width, height, 1 /* plane */ , + depth /* bits per pixel */ , NULL); + img->width = width; + img->height = height; + img->depth = depth; + } + return (img); + +} + +void +XImageFree(XImage *img) +{ + if (img) { + XpmFree(img); + } +} +void +XDestroyImage(XImage *img) +{ + if (img) { + DeleteObject(img->bitmap); /* check return ??? */ + XImageFree(img); + } +} + +#endif diff --git a/src/xpm/simx.h b/src/xpm/simx.h new file mode 100644 index 0000000000..23e8a1a297 --- /dev/null +++ b/src/xpm/simx.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* simx.h: 0.1a * +* * +* This emulates some Xlib functionality for MSW. It's not a general solution, * +* it is close related to XPM-lib. It is only intended to satisfy what is need * +* there. Thus allowing to read XPM files under MS windows. * +* * +* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de) * +\*****************************************************************************/ + + +#ifndef _SIMX_H +#define _SIMX_H + +#ifdef FOR_MSW + +#include "windows.h" /* MS windows GDI types */ + +/* + * minimal portability layer between ansi and KR C + */ +/* this comes from xpm.h, and is here again, to avoid complicated + includes, since this is included from xpm.h */ +/* these defines get undefed at the end of this file */ +#if __STDC__ || defined(__cplusplus) || defined(c_plusplus) + /* ANSI || C++ */ +#define FUNC(f, t, p) extern t f p +#define LFUNC(f, t, p) static t f p +#else /* k&R */ +#define FUNC(f, t, p) extern t f() +#define LFUNC(f, t, p) static t f() +#endif + + +FUNC(boundCheckingMalloc, void *, (long s)); +FUNC(boundCheckingCalloc, void *, (long num, long s)); +FUNC(boundCheckingRealloc, void *, (void *p, long s)); + +/* define MSW types for X window types, + I don't know much about MSW, but the following defines do the job */ + +typedef HDC Display; /* this should be similar */ +typedef void *Screen; /* not used */ +typedef void *Visual; /* not used yet, is for GRAY, COLOR, + * MONO */ + +typedef void *Colormap; /* should be COLORPALETTE, not done + * yet */ + +typedef COLORREF Pixel; + +#define PIXEL_ALREADY_TYPEDEFED /* to let xpm.h know about it */ + +typedef struct { + Pixel pixel; + BYTE red, green, blue; +} XColor; + +typedef struct { + HBITMAP bitmap; + unsigned int width; + unsigned int height; + unsigned int depth; +} XImage; + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif +/* some replacements for X... functions */ + +/* XDefaultXXX */ + FUNC(XDefaultVisual, Visual *, (Display *display, Screen *screen)); + FUNC(XDefaultScreen, Screen *, (Display *d)); + FUNC(XDefaultColormap, Colormap *, (Display *display, Screen *screen)); + FUNC(XDefaultDepth, int, (Display *d, Screen *s)); + +/* color related */ + FUNC(XParseColor, int, (Display *, Colormap *, char *, XColor *)); + FUNC(XAllocColor, int, (Display *, Colormap *, XColor *)); + FUNC(XQueryColors, void, (Display *display, Colormap *colormap, + XColor *xcolors, int ncolors)); + FUNC(XFreeColors, int, (Display *d, Colormap cmap, + unsigned long pixels[], + int npixels, unsigned long planes)); +/* XImage */ + FUNC(XCreateImage, XImage *, (Display *, Visual *, int depth, int format, + int x, int y, int width, int height, + int pad, int foo)); + +/* free and destroy bitmap */ + FUNC(XDestroyImage, void /* ? */ , (XImage *)); +/* free only, bitmap remains */ + FUNC(XImageFree, void, (XImage *)); +#if defined(__cplusplus) || defined(c_plusplus) +} /* end of extern "C" */ +#endif /* cplusplus */ + +#define ZPixmap 1 /* not really used */ + +#ifndef True +#define True 1 +#define False 0 +#endif + +/* +#ifndef Bool +typedef BOOL Bool; +#endif +*/ + +/* make these local here, simx.c gets the same from xpm.h */ +#undef LFUNC +#undef FUNC + +#endif /* def FOR_MSW */ + +#endif /* _SIMX_H */ diff --git a/src/xpm/wrffrdat.c b/src/xpm/wrffrdat.c new file mode 100644 index 0000000000..6fe3734195 --- /dev/null +++ b/src/xpm/wrffrdat.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmWrFFrData.c: * +* * +* XPM library * +* Parse an Xpm array and write a file that corresponds to it. * +* * +* Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com * +\*****************************************************************************/ + +#include "xpm34.h" +#include "xpm34p.h" + +int +XpmWriteFileFromData(char *filename, char **data) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + info.valuemask = XpmReturnComments | XpmReturnExtensions; + + ErrorStatus = XpmCreateXpmImageFromData(data, &image, &info); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + ErrorStatus = XpmWriteFileFromXpmImage(filename, &image, &info); + + XpmFreeXpmImage(&image); + XpmFreeXpmInfo(&info); + + return (ErrorStatus); +} diff --git a/src/xpm/wrffri.c b/src/xpm/wrffri.c new file mode 100644 index 0000000000..29dc4096dd --- /dev/null +++ b/src/xpm/wrffri.c @@ -0,0 +1,258 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmWrFFrI.c: * +* * +* XPM library * +* Write an image and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" +#ifdef FOR_MSW +#include "ctype.h" +#endif + +#include + +LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors)); + +LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height, + unsigned int cpp, unsigned int *pixels, + XpmColor *colors)); + +LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext, + unsigned int num)); + +int +XpmWriteFileFromImage(Display *display, char *filename, XImage *image, XImage *shapeimage, XpmAttributes *attributes) +{ + XpmImage xpmimage; + XpmInfo info; + int ErrorStatus; + + /* create an XpmImage from the image */ + ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage, + &xpmimage, attributes); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* write the file from the XpmImage */ + if (attributes) { + xpmSetInfo(&info, attributes); + ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info); + } else + ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL); + + /* free the XpmImage */ + XpmFreeXpmImage(&xpmimage); + + return (ErrorStatus); +} + +int +XpmWriteFileFromXpmImage(char *filename, XpmImage *image, XpmInfo *info) +{ + xpmData mdata; + char *name, *dot, *s, new_name[BUFSIZ]; + int ErrorStatus; + int len, i; + + /* open file to write */ + if ((ErrorStatus = xpmWriteFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* figure out a name */ + if (filename) { +#ifdef VMS + name = filename; +#else +#ifdef FOR_MSW + if (!(name = strchr(filename, '\\'))) +#else + if (!(name = strchr(filename, '/'))) +#endif + name = filename; + else + name++; +#endif + if (dot = strchr(name, '.')) { + strcpy(new_name, name); +#ifdef FOR_MSW + // Convert to lower case + len = strlen(new_name); + for (i = 0; i < len; i++) + new_name[i] = tolower(new_name[i]); +#endif + /* change '.' to '_' to get a valid C syntax name */ + name = s = new_name; + while (dot = strchr(s, '.')) { + *dot = '_'; + s = dot; + } + } + } else + name = "image_name"; + + /* write the XpmData from the XpmImage */ + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmWriteData(&mdata, image, name, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} + +int +xpmWriteData(xpmData *mdata, XpmImage *image, char *name, XpmInfo *info) +{ + /* calculation variables */ + unsigned int cmts, extensions; + FILE *file; + int ErrorStatus; + + /* store this to speed up */ + file = mdata->stream.file; + + cmts = info && (info->valuemask & XpmComments); + extensions = info && (info->valuemask & XpmExtensions) + && info->nextensions; + + /* print the header line */ + fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name); + + /* print the hints line */ + if (cmts && info->hints_cmt) + fprintf(file, "/*%s*/\n", info->hints_cmt); + + fprintf(file, "\"%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); + + if (info && (info->valuemask & XpmHotspot)) + fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot); + + if (extensions) + fprintf(file, " XPMEXT"); + + fprintf(file, "\",\n"); + + /* print colors */ + if (cmts && info->colors_cmt) + fprintf(file, "/*%s*/\n", info->colors_cmt); + + WriteColors(file, image->colorTable, image->ncolors); + + /* print pixels */ + if (cmts && info->pixels_cmt) + fprintf(file, "/*%s*/\n", info->pixels_cmt); + + ErrorStatus = WritePixels(file, image->width, image->height, image->cpp, + image->data, image->colorTable); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* print extensions */ + if (extensions) + WriteExtensions(file, info->extensions, info->nextensions); + + /* close the array */ + fprintf(file, "};\n"); + + return (XpmSuccess); +} + +static void +WriteColors(FILE *file, XpmColor *colors, unsigned int ncolors) +{ + unsigned int a, key; + char *s; + char **defaults; + + for (a = 0; a < ncolors; a++, colors++) { + + defaults = (char **) colors; + fprintf(file, "\"%s", *defaults++); + + for (key = 1; key <= NKEYS; key++, defaults++) { + if (s = *defaults) + fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s); + } + fprintf(file, "\",\n"); + } +} + + +static int +WritePixels(FILE *file, unsigned int width, unsigned int height, unsigned int cpp, unsigned int *pixels, XpmColor *colors) +{ + char *s, *p, *buf; + unsigned int x, y, h; + + h = height - 1; + p = buf = (char *) XpmMalloc(width * cpp + 3); + if (!buf) + return (XpmNoMemory); + *buf = '"'; + p++; + for (y = 0; y < h; y++) { + s = p; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s++ = '"'; + *s = '\0'; + fprintf(file, "%s,\n", buf); + } + /* duplicate some code to avoid a test in the loop */ + s = p; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s++ = '"'; + *s = '\0'; + fprintf(file, "%s", buf); + + XpmFree(buf); + return (XpmSuccess); +} + +static void +WriteExtensions(FILE *file, XpmExtension *ext, unsigned int num) +{ + unsigned int x, y, n; + char **line; + + for (x = 0; x < num; x++, ext++) { + fprintf(file, ",\n\"XPMEXT %s\"", ext->name); + n = ext->nlines; + for (y = 0, line = ext->lines; y < n; y++, line++) + fprintf(file, ",\n\"%s\"", *line); + } + fprintf(file, ",\n\"XPMENDEXT\""); +} diff --git a/src/xpm/wrffrp.c b/src/xpm/wrffrp.c new file mode 100644 index 0000000000..3e2e6ca5a5 --- /dev/null +++ b/src/xpm/wrffrp.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +#include "xpm34.h" + +#ifndef FOR_MSW + +/*****************************************************************************\ +* XpmWrFFrP.c: * +* * +* XPM library * +* Write a pixmap and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpm34p.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include +#else +#include +#endif +#endif + +int +XpmWriteFileFromPixmap(Display *display, char *filename, Pixmap pixmap, Pixmap shapemask, XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* write to the file */ + ErrorStatus = XpmWriteFileFromImage(display, filename, ximage, shapeimage, + attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} +#endif diff --git a/src/xpm/xpm34.h b/src/xpm/xpm34.h new file mode 100644 index 0000000000..fba32dbc2b --- /dev/null +++ b/src/xpm/xpm34.h @@ -0,0 +1,555 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* xpm.h: * +* * +* XPM library * +* Include file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#ifndef XPM_h +#define XPM_h + +#if defined(_WINDOWS) || defined(__WXMSW__) || defined(WIN32) +#define FOR_MSW +#endif + +/* + * first some identification numbers: + * the following revision numbers is determined with the following rule: + * SO Major number = LIB minor version number. + * SO Minor number = LIB sub-minor version number. + * e.g: Xpm version 3.2f + * we forget the 3 which is the format number, 2 gives 2, and f gives 6. + * thus we have XpmVersion = 2 and XpmRevision = 6 + * which gives SOXPMLIBREV = 2.6 + * + * Then the XpmIncludeVersion number is built with the following rule: + * (XpmFormat*100 + XpmVersion)*100 + XpmRevision + */ +#define XpmFormat 3 +#define XpmVersion 4 +#define XpmRevision 2 + +#define XpmIncludeVersion 30402 + +#ifndef XPM_NUMBERS + +#ifdef VMS +#include "decw$include:Xlib.h" +#include "decw$include:Xutil.h" +#else /* VMS */ +#ifdef FOR_MSW +#define SYSV /* uses memcpy string.h etc. */ +#include +#include "simx.h" /* defines some X stuff using MSW types */ +#ifndef __GNUWIN32__ +#define NEED_STRCASECMP /* at least for MSVC++ */ +#endif +#else /* FOR_MSW */ +#include +#include +#include /* HEDU */ +#endif /* FOR_MSW */ +#endif /* VMS */ + +/* let's define Pixel if it is not done yet */ +#if ! defined(_XtIntrinsic_h) && ! defined(PIXEL_ALREADY_TYPEDEFED) +typedef unsigned long Pixel; /* Index into colormap */ +#define PIXEL_ALREADY_TYPEDEFED +#endif + +/* Return ErrorStatus codes: + * null if full success + * positive if partial success + * negative if failure + */ + +#define XpmColorError 1 +#define XpmSuccess 0 +#define XpmOpenFailed -1 +#define XpmFileInvalid -2 +#define XpmNoMemory -3 +#define XpmColorFailed -4 + +/* the following should help people wanting to use their own functions */ +#define XpmFree(ptr) free(ptr) + +typedef struct { + char *name; /* Symbolic color name */ + char *value; /* Color value */ + Pixel pixel; /* Color pixel */ +} XpmColorSymbol; + +typedef struct { + char *name; /* name of the extension */ + unsigned int nlines; /* number of lines in this extension */ + char **lines; /* pointer to the extension array of strings */ +} XpmExtension; + +typedef struct { + char *string; /* characters string */ + char *symbolic; /* symbolic name */ + char *m_color; /* monochrom default */ + char *g4_color; /* 4 level grayscale default */ + char *g_color; /* other level grayscale default */ + char *c_color; /* color default */ +} XpmColor; + +typedef struct { + unsigned int width; /* image width */ + unsigned int height; /* image height */ + unsigned int cpp; /* number of characters per pixel */ + unsigned int ncolors; /* number of colors */ + XpmColor *colorTable; /* list of related colors */ + unsigned int *data; /* image data */ +} XpmImage; + +typedef struct { + unsigned long valuemask; /* Specifies which attributes are defined */ + char *hints_cmt; /* Comment of the hints section */ + char *colors_cmt; /* Comment of the colors section */ + char *pixels_cmt; /* Comment of the pixels section */ + unsigned int x_hotspot; /* Returns the x hotspot's coordinate */ + unsigned int y_hotspot; /* Returns the y hotspot's coordinate */ + unsigned int nextensions; /* number of extensions */ + XpmExtension *extensions; /* pointer to array of extensions */ +} XpmInfo; + +typedef struct { + unsigned long valuemask; /* Specifies which attributes are + * defined */ + + Visual *visual; /* Specifies the visual to use */ + Colormap colormap; /* Specifies the colormap to use */ + unsigned int depth; /* Specifies the depth */ + unsigned int width; /* Returns the width of the created + * pixmap */ + unsigned int height; /* Returns the height of the created + * pixmap */ + unsigned int x_hotspot; /* Returns the x hotspot's + * coordinate */ + unsigned int y_hotspot; /* Returns the y hotspot's + * coordinate */ + unsigned int cpp; /* Specifies the number of char per + * pixel */ + Pixel *pixels; /* List of used color pixels */ + unsigned int npixels; /* Number of pixels */ + XpmColorSymbol *colorsymbols; /* Array of color symbols to + * override */ + unsigned int numsymbols; /* Number of symbols */ + char *rgb_fname; /* RGB text file name */ + unsigned int nextensions; /* number of extensions */ + XpmExtension *extensions; /* pointer to array of extensions */ + + unsigned int ncolors; /* Number of colors */ + XpmColor *colorTable; /* Color table pointer */ +/* 3.2 backward compatibility code */ + char *hints_cmt; /* Comment of the hints section */ + char *colors_cmt; /* Comment of the colors section */ + char *pixels_cmt; /* Comment of the pixels section */ +/* end 3.2 bc */ + unsigned int mask_pixel; /* Transparent pixel's color table + * index */ + + /* Color Allocation Directives */ + unsigned int exactColors; /* Only use exact colors for visual */ + unsigned int closeness; /* Allowable RGB deviation */ + unsigned int red_closeness; /* Allowable red deviation */ + unsigned int green_closeness; /* Allowable green deviation */ + unsigned int blue_closeness; /* Allowable blue deviation */ + int color_key; /* Use colors from this color set */ + +} XpmAttributes; + +/* XpmAttributes value masks bits */ +#define XpmVisual (1L<<0) +#define XpmColormap (1L<<1) +#define XpmDepth (1L<<2) +#define XpmSize (1L<<3) /* width & height */ +#define XpmHotspot (1L<<4) /* x_hotspot & y_hotspot */ +#define XpmCharsPerPixel (1L<<5) +#define XpmColorSymbols (1L<<6) +#define XpmRgbFilename (1L<<7) +/* 3.2 backward compatibility code */ +#define XpmInfos (1L<<8) +#define XpmReturnInfos XpmInfos +/* end 3.2 bc */ +#define XpmReturnPixels (1L<<9) +#define XpmExtensions (1L<<10) +#define XpmReturnExtensions XpmExtensions + +#define XpmExactColors (1L<<11) +#define XpmCloseness (1L<<12) +#define XpmRGBCloseness (1L<<13) +#define XpmColorKey (1L<<14) + +#define XpmColorTable (1L<<15) +#define XpmReturnColorTable XpmColorTable + +/* XpmInfo value masks bits */ +#define XpmComments XpmInfos +#define XpmReturnComments XpmComments + +/* XpmAttributes mask_pixel value when there is no mask */ +#ifndef FOR_MSW +#define XpmUndefPixel 0x80000000 +#else +/* int is only 16 bit for MSW */ +#define XpmUndefPixel 0x8000 +#endif + +/* + * color keys for visual type, they must fit along with the number key of + * each related element in xpmColorKeys[] defined in xpmP.h + */ +#define XPM_MONO 2 +#define XPM_GREY4 3 +#define XPM_GRAY4 3 +#define XPM_GREY 4 +#define XPM_GRAY 4 +#define XPM_COLOR 5 + + +/* + * minimal portability layer between ansi and KR C + */ + +/* forward declaration of functions with prototypes */ + +#if __STDC__ || defined(__cplusplus) || defined(c_plusplus) + /* ANSI || C++ */ +#define FUNC(f, t, p) extern t f p +#define LFUNC(f, t, p) static t f p +/* #define LFUNC(f, t, p) t f p */ +#else /* K&R */ +#define FUNC(f, t, p) extern t f() +#define LFUNC(f, t, p) static t f() +/* #define LFUNC(f, t, p) t f() */ +#endif /* end of K&R */ + + +/* + * functions declarations + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* For Microsoft C++ at any rate, the FUNC macro just doesn't work: it causes + * arguments to be corrupted espec. in XpmWriteFileFromXpmImage. + * So, define all prototypes explicitly. + */ +#ifdef _MSC_VER + +/* FOR_MSW, all ..Pixmap.. are excluded, only the ..XImage.. are used */ + + int XpmCreateImageFromData(Display *display, + char **data, + XImage **image_return, + XImage **shapemask_return, + XpmAttributes *attributes); + + int XpmCreateDataFromImage(Display *display, + char ***data_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes); + + int XpmReadFileToImage(Display *display, + char *filename, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes); + + int XpmWriteFileFromImage(Display *display, + char *filename, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes); + + int XpmCreateImageFromBuffer(Display *display, + char *buffer, + XImage **image_return, + XImage **shapemask_return, + XpmAttributes *attributes); + + int XpmReadFileToBuffer(char *filename, char **buffer_return); + int XpmWriteFileFromBuffer(char *filename, char *buffer); + + int XpmReadFileToData(char *filename, char ***data_return); + int XpmWriteFileFromData(char *filename, char **data); + + int XpmAttributesSize(); + void XpmFreeAttributes(XpmAttributes *attributes); + void XpmFreeExtensions(XpmExtension *extensions, + int nextensions); + + void XpmFreeXpmImage(XpmImage *image); + void XpmFreeXpmInfo(XpmInfo *info); + char *XpmGetErrorString(int errcode); + int XpmLibraryVersion(); + + /* XpmImage functions */ + int XpmReadFileToXpmImage(char *filename, + XpmImage *image, + XpmInfo *info); + + int XpmWriteFileFromXpmImage(char *filename, + XpmImage *image, + XpmInfo *info); + + int XpmWriteFileFromXpmImage(char *filename, XpmImage *image, XpmInfo *info); + + int XpmCreateImageFromXpmImage(Display *display, + XpmImage *image, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes); + + int XpmCreateXpmImageFromImage(Display *display, + XImage *image, + XImage *shapeimage, + XpmImage *xpmimage, + XpmAttributes *attributes); + int XpmCreateDataFromXpmImage(char ***data_return, + XpmImage *image, + XpmInfo *info); + + int XpmCreateXpmImageFromData(char **data, + XpmImage *image, + XpmInfo *info); + + int XpmCreateXpmImageFromBuffer(char *buffer, + XpmImage *image, + XpmInfo *info); + + int XpmCreateBufferFromXpmImage(char **buffer_return, + XpmImage *image, + XpmInfo *info); + +#else // _MSC_VER + +/* FOR_MSW, all ..Pixmap.. are excluded, only the ..XImage.. are used */ + +#ifndef FOR_MSW + FUNC(XpmCreatePixmapFromData, int, (Display *display, + Drawable d, + char **data, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateDataFromPixmap, int, (Display *display, + char ***data_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes)); + + FUNC(XpmReadFileToPixmap, int, (Display *display, + Drawable d, + char *filename, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmWriteFileFromPixmap, int, (Display *display, + char *filename, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes)); +#endif /* ndef FOR_MSW */ + + FUNC(XpmCreateImageFromData, int, (Display *display, + char **data, + XImage **image_return, + XImage **shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateDataFromImage, int, (Display *display, + char ***data_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes)); + + FUNC(XpmReadFileToImage, int, (Display *display, + char *filename, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes)); + + FUNC(XpmWriteFileFromImage, int, (Display *display, + char *filename, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes)); + + FUNC(XpmCreateImageFromBuffer, int, (Display *display, + char *buffer, + XImage **image_return, + XImage **shapemask_return, + XpmAttributes *attributes)); +#ifndef FOR_MSW + FUNC(XpmCreatePixmapFromBuffer, int, (Display *display, + Drawable d, + char *buffer, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateBufferFromImage, int, (Display *display, + char **buffer_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes)); + + FUNC(XpmCreateBufferFromPixmap, int, (Display *display, + char **buffer_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes)); +#endif /* ndef FOR_MSW */ + FUNC(XpmReadFileToBuffer, int, (char *filename, char **buffer_return)); + FUNC(XpmWriteFileFromBuffer, int, (char *filename, char *buffer)); + + FUNC(XpmReadFileToData, int, (char *filename, char ***data_return)); + FUNC(XpmWriteFileFromData, int, (char *filename, char **data)); + + FUNC(XpmAttributesSize, int, ()); + FUNC(XpmFreeAttributes, void, (XpmAttributes *attributes)); + FUNC(XpmFreeExtensions, void, (XpmExtension *extensions, + int nextensions)); + + FUNC(XpmFreeXpmImage, void, (XpmImage *image)); + FUNC(XpmFreeXpmInfo, void, (XpmInfo *info)); + FUNC(XpmGetErrorString, char *, (int errcode)); + FUNC(XpmLibraryVersion, int, ()); + + /* XpmImage functions */ + FUNC(XpmReadFileToXpmImage, int, (char *filename, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmWriteFileFromXpmImage, int, (char *filename, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmWriteFileFromXpmImage, int, (char *filename, XpmImage *image, XpmInfo *info)); +/* extern int XpmWriteFileFromXpmImage(char *filename, XpmImage *image, XpmInfo *info); */ + +#ifndef FOR_MSW + FUNC(XpmCreatePixmapFromXpmImage, int, (Display *display, + Drawable d, + XpmImage *image, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); +#endif + FUNC(XpmCreateImageFromXpmImage, int, (Display *display, + XpmImage *image, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateXpmImageFromImage, int, (Display *display, + XImage *image, + XImage *shapeimage, + XpmImage *xpmimage, + XpmAttributes *attributes)); +#ifndef FOR_MSW + FUNC(XpmCreateXpmImageFromPixmap, int, (Display *display, + Pixmap pixmap, + Pixmap shapemask, + XpmImage *xpmimage, + XpmAttributes *attributes)); +#endif + FUNC(XpmCreateDataFromXpmImage, int, (char ***data_return, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmCreateXpmImageFromData, int, (char **data, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmCreateXpmImageFromBuffer, int, (char *buffer, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmCreateBufferFromXpmImage, int, (char **buffer_return, + XpmImage *image, + XpmInfo *info)); + +#endif // _MSC_VER + +#ifdef __cplusplus +} /* for C++ V2.0 */ +#endif + + +/* backward compatibility */ + +/* for version 3.0c */ +#define XpmPixmapColorError XpmColorError +#define XpmPixmapSuccess XpmSuccess +#define XpmPixmapOpenFailed XpmOpenFailed +#define XpmPixmapFileInvalid XpmFileInvalid +#define XpmPixmapNoMemory XpmNoMemory +#define XpmPixmapColorFailed XpmColorFailed + +#define XpmReadPixmapFile(dpy, d, file, pix, mask, att) \ + XpmReadFileToPixmap(dpy, d, file, pix, mask, att) +#define XpmWritePixmapFile(dpy, file, pix, mask, att) \ + XpmWriteFileFromPixmap(dpy, file, pix, mask, att) + +/* for version 3.0b */ +#define PixmapColorError XpmColorError +#define PixmapSuccess XpmSuccess +#define PixmapOpenFailed XpmOpenFailed +#define PixmapFileInvalid XpmFileInvalid +#define PixmapNoMemory XpmNoMemory +#define PixmapColorFailed XpmColorFailed + +#define ColorSymbol XpmColorSymbol + +#define XReadPixmapFile(dpy, d, file, pix, mask, att) \ + XpmReadFileToPixmap(dpy, d, file, pix, mask, att) +#define XWritePixmapFile(dpy, file, pix, mask, att) \ + XpmWriteFileFromPixmap(dpy, file, pix, mask, att) +#define XCreatePixmapFromData(dpy, d, data, pix, mask, att) \ + XpmCreatePixmapFromData(dpy, d, data, pix, mask, att) +#define XCreateDataFromPixmap(dpy, data, pix, mask, att) \ + XpmCreateDataFromPixmap(dpy, data, pix, mask, att) + +#endif /* XPM_NUMBERS */ +#endif diff --git a/src/xpm/xpm34p.h b/src/xpm/xpm34p.h new file mode 100644 index 0000000000..31a7008484 --- /dev/null +++ b/src/xpm/xpm34p.h @@ -0,0 +1,304 @@ +/* + * Copyright (C) 1989-94 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* xpmP.h: * +* * +* XPM library * +* Private Include file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#ifndef XPMP_h +#define XPMP_h + +#include "xpm34.h" + +/* + * lets try to solve include files + */ +#ifdef VMS + +#include "sys$library:stdio.h" +#include "sys$library:string.h" + +#else /* VMS */ + +#include +/* stdio.h doesn't declare popen on a Sequent DYNIX OS */ +#ifdef sequent +extern FILE *popen(); +#endif + +#if defined(SYSV) || defined(SVR4) +#include + +#ifndef index +#define index strchr +#endif + +#ifndef rindex +#define rindex strrchr +#endif + +#else /* defined(SYSV) || defined(SVR4) */ +#include +#endif + +#endif /* VMS */ + + +#if (defined(SYSV) || defined(SVR4) || defined(VMS)) && !defined(__sgi) +#define bcopy(source, dest, count) memcpy(dest, source, count) +#define bzero(b, len) memset(b, 0, len) +#endif + + +/* the following should help people wanting to use their own functions */ +#ifndef FOR_MSW +#define XpmMalloc(size) malloc((size)) +#define XpmRealloc(ptr, size) realloc((ptr), (size)) +#define XpmCalloc(nelem, elsize) calloc((nelem), (elsize)) +#else +/* checks for mallocs bigger than 64K */ +#define XpmMalloc(size) boundCheckingMalloc((long)(size))/* in simx.[ch] */ +#define XpmRealloc(ptr, size) boundCheckingRealloc((ptr),(long)(size)) +#define XpmCalloc(nelem, elsize) \ + boundCheckingCalloc((long)(nelem),(long) (elsize)) +#endif + + +typedef struct { + unsigned int type; + union { + FILE *file; + char **data; + } stream; + char *cptr; + unsigned int line; + int CommentLength; + char Comment[BUFSIZ]; + char *Bcmt, *Ecmt, Bos, Eos; + int format; /* 1 if XPM1, 0 otherwise */ +} xpmData; + +#define XPMARRAY 0 +#define XPMFILE 1 +#define XPMPIPE 2 +#define XPMBUFFER 3 + +#define EOL '\n' +#define TAB '\t' +#define SPC ' ' + +typedef struct { + char *type; /* key word */ + char *Bcmt; /* string beginning comments */ + char *Ecmt; /* string ending comments */ + char Bos; /* character beginning strings */ + char Eos; /* character ending strings */ + char *Strs; /* strings separator */ + char *Dec; /* data declaration string */ + char *Boa; /* string beginning assignment */ + char *Eoa; /* string ending assignment */ +} xpmDataType; + +extern xpmDataType xpmDataTypes[]; + +/* + * rgb values and ascii names (from rgb text file) rgb values, + * range of 0 -> 65535 color mnemonic of rgb value + */ +typedef struct { + int r, g, b; + char *name; +} xpmRgbName; + +/* Maximum number of rgb mnemonics allowed in rgb text file. */ +#define MAX_RGBNAMES 1024 + +extern char *xpmColorKeys[]; + +#define TRANSPARENT_COLOR "None" /* this must be a string! */ + +/* number of xpmColorKeys */ +#define NKEYS 5 + +/* XPM private routines */ + +FUNC(xpmWriteData, int, (xpmData *mdata, XpmImage *image, char *name, + XpmInfo *info)); + +FUNC(xpmParseData, int, (xpmData *data, XpmImage *image, XpmInfo *info)); + +FUNC(xpmFreeColorTable, void, (XpmColor *colorTable, int ncolors)); + +FUNC(xpmInitAttributes, void, (XpmAttributes *attributes)); + +FUNC(xpmInitXpmImage, void, (XpmImage *image)); + +FUNC(xpmInitXpmInfo, void, (XpmInfo *info)); + +FUNC(xpmSetInfoMask, void, (XpmInfo *info, XpmAttributes *attributes)); +FUNC(xpmSetInfo, void, (XpmInfo *info, XpmAttributes *attributes)); +FUNC(xpmSetAttributes, void, (XpmAttributes *attributes, XpmImage *image, + XpmInfo *info)); + +#ifndef FOR_MSW +FUNC(xpmCreatePixmapFromImage, void, (Display *display, Drawable d, + XImage *ximage, Pixmap *pixmap_return)); + +FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap, + XImage **ximage_return, + unsigned int *width, + unsigned int *height)); +#endif + +/* I/O utility */ + +FUNC(xpmNextString, int, (xpmData *mdata)); +FUNC(xpmNextUI, int, (xpmData *mdata, unsigned int *ui_return)); +FUNC(xpmGetString, int, (xpmData *mdata, char **sptr, unsigned int *l)); + +#define xpmGetC(mdata) \ + ((!mdata->type || mdata->type == XPMBUFFER) ? \ + (*mdata->cptr++) : (getc(mdata->stream.file))) + +FUNC(xpmNextWord, unsigned int, + (xpmData *mdata, char *buf, unsigned int buflen)); +FUNC(xpmGetCmt, int, (xpmData *mdata, char **cmt)); +FUNC(xpmReadFile, int, (char *filename, xpmData *mdata)); +FUNC(xpmWriteFile, int, (char *filename, xpmData *mdata)); +FUNC(xpmOpenArray, void, (char **data, xpmData *mdata)); +FUNC(xpmDataClose, int, (xpmData *mdata)); +FUNC(xpmParseHeader, int, (xpmData *mdata)); +FUNC(xpmOpenBuffer, void, (char *buffer, xpmData *mdata)); + +/* RGB utility */ + +FUNC(xpmReadRgbNames, int, (char *rgb_fname, xpmRgbName *rgbn)); +FUNC(xpmGetRgbName, char *, (xpmRgbName *rgbn, int rgbn_max, + int red, int green, int blue)); +FUNC(xpmFreeRgbNames, void, (xpmRgbName *rgbn, int rgbn_max)); +#ifdef FOR_MSW +FUNC(xpmGetRGBfromName,int, (char *name, int *r, int *g, int *b)); +#endif + +FUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp, + register XImage *img)); +FUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp, + register XImage *img)); + +/* + * Macros + * + * The XYNORMALIZE macro determines whether XY format data requires + * normalization and calls a routine to do so if needed. The logic in + * this module is designed for LSBFirst byte and bit order, so + * normalization is done as required to present the data in this order. + * + * The ZNORMALIZE macro performs byte and nibble order normalization if + * required for Z format data. + * + * The XYINDEX macro computes the index to the starting byte (char) boundary + * for a bitmap_unit containing a pixel with coordinates x and y for image + * data in XY format. + * + * The ZINDEX* macros compute the index to the starting byte (char) boundary + * for a pixel with coordinates x and y for image data in ZPixmap format. + * + */ + +#define XYNORMALIZE(bp, img) \ + if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \ + xpm_xynormalizeimagebits((unsigned char *)(bp), img) + +#define ZNORMALIZE(bp, img) \ + if (img->byte_order == MSBFirst) \ + xpm_znormalizeimagebits((unsigned char *)(bp), img) + +#define XYINDEX(x, y, img) \ + ((y) * img->bytes_per_line) + \ + (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) + +#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \ + (((x) * img->bits_per_pixel) >> 3) + +#define ZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2) + +#define ZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1) + +#define ZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x) + +#define ZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3) + +#if __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +/* + * there are structures and functions related to hastable code + */ + +typedef struct _xpmHashAtom { + char *name; + void *data; +} *xpmHashAtom; + +typedef struct { + int size; + int limit; + int used; + xpmHashAtom *atomTable; +} xpmHashTable; + +FUNC(xpmHashTableInit, int, (xpmHashTable *table)); +FUNC(xpmHashTableFree, void, (xpmHashTable *table)); +FUNC(xpmHashSlot, xpmHashAtom *, (xpmHashTable *table, char *s)); +FUNC(xpmHashIntern, int, (xpmHashTable *table, char *tag, void *data)); + +#define HashAtomData(i) ((void *)i) +#define HashColorIndex(slot) ((unsigned int)((*slot)->data)) +#define USE_HASHTABLE (cpp > 2 && ncolors > 4) + +#ifdef NEED_STRDUP +FUNC(strdup, char *, (char *s1)); +#endif + +#ifdef NEED_STRCASECMP +FUNC(strcasecmp, int, (char *s1, char *s2)); +#endif + +FUNC(atoui, unsigned int, (char *p, unsigned int l, unsigned int *ui_return)); + +#endif -- 2.47.2