From aafaabc4a0bfab6544e085ee504ad69de4a5ddb1 Mon Sep 17 00:00:00 2001 From: Kaleb Keithley Date: Fri, 14 Nov 2003 16:48:24 +0000 Subject: Initial revision --- CHANGES | 957 ++++++++++++++++++++ COPYRIGHT | 31 + FAQ.html | 344 +++++++ FILES | 68 ++ README.AMIGA | 10 + README.MSW | 127 +++ README.html | 303 +++++++ cxpm/cxpm.c | 153 ++++ cxpm/cxpm.man | 49 + include/X11/xpm.h | 502 +++++++++++ src/Attrib.c | 302 +++++++ src/CrBufFrI.c | 401 +++++++++ src/CrBufFrP.c | 75 ++ src/CrDatFrI.c | 341 +++++++ src/CrDatFrP.c | 74 ++ src/CrIFrBuf.c | 115 +++ src/CrIFrDat.c | 120 +++ src/CrIFrP.c | 55 ++ src/CrPFrBuf.c | 76 ++ src/CrPFrDat.c | 79 ++ src/CrPFrI.c | 59 ++ src/Image.c | 61 ++ src/Info.c | 124 +++ src/RdFToBuf.c | 118 +++ src/RdFToDat.c | 65 ++ src/RdFToI.c | 224 +++++ src/RdFToP.c | 75 ++ src/WrFFrBuf.c | 55 ++ src/WrFFrDat.c | 59 ++ src/WrFFrI.c | 360 ++++++++ src/WrFFrP.c | 74 ++ src/XpmI.h | 314 +++++++ src/amigax.c | 382 ++++++++ src/amigax.h | 151 ++++ src/create.c | 2484 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/data.c | 476 ++++++++++ src/hashtab.c | 234 +++++ src/misc.c | 124 +++ src/parse.c | 749 ++++++++++++++++ src/rgb.c | 282 ++++++ src/rgbtab.h | 292 ++++++ src/scan.c | 1007 +++++++++++++++++++++ src/simx.c | 290 ++++++ src/simx.h | 139 +++ sxpm/plaid.xpm | 34 + sxpm/plaid_ext.xpm | 43 + sxpm/plaid_mask.xpm | 35 + sxpm/sxpm.c | 709 +++++++++++++++ sxpm/sxpm.man | 131 +++ xpm.PS.gz | Bin 0 -> 49010 bytes 50 files changed, 13332 insertions(+) create mode 100644 CHANGES create mode 100644 COPYRIGHT create mode 100644 FAQ.html create mode 100644 FILES create mode 100644 README.AMIGA create mode 100644 README.MSW create mode 100644 README.html create mode 100644 cxpm/cxpm.c create mode 100644 cxpm/cxpm.man create mode 100644 include/X11/xpm.h create mode 100644 src/Attrib.c create mode 100644 src/CrBufFrI.c create mode 100644 src/CrBufFrP.c create mode 100644 src/CrDatFrI.c create mode 100644 src/CrDatFrP.c create mode 100644 src/CrIFrBuf.c create mode 100644 src/CrIFrDat.c create mode 100644 src/CrIFrP.c create mode 100644 src/CrPFrBuf.c create mode 100644 src/CrPFrDat.c create mode 100644 src/CrPFrI.c create mode 100644 src/Image.c create mode 100644 src/Info.c create mode 100644 src/RdFToBuf.c create mode 100644 src/RdFToDat.c create mode 100644 src/RdFToI.c create mode 100644 src/RdFToP.c create mode 100644 src/WrFFrBuf.c create mode 100644 src/WrFFrDat.c create mode 100644 src/WrFFrI.c create mode 100644 src/WrFFrP.c create mode 100644 src/XpmI.h create mode 100644 src/amigax.c create mode 100644 src/amigax.h create mode 100644 src/create.c create mode 100644 src/data.c create mode 100644 src/hashtab.c create mode 100644 src/misc.c create mode 100644 src/parse.c create mode 100644 src/rgb.c create mode 100644 src/rgbtab.h create mode 100644 src/scan.c create mode 100644 src/simx.c create mode 100644 src/simx.h create mode 100644 sxpm/plaid.xpm create mode 100644 sxpm/plaid_ext.xpm create mode 100644 sxpm/plaid_mask.xpm create mode 100644 sxpm/sxpm.c create mode 100644 sxpm/sxpm.man create mode 100644 xpm.PS.gz diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..b90e6cd --- /dev/null +++ b/CHANGES @@ -0,0 +1,957 @@ +/* + * Copyright (C) 1989-95 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.4k (98/03/18) + + ENHANCEMENTS: + - A new program called cxpm is provided to check on XPM files and help + figuring out where the file might be invalid. + - The FAQ and README are now in HTML. + + BUGS CORRECTED: + - A bug in writing pixmaps out on an 32 bit depth visual and MSBFirst + machine. + - patch from Uwe Langenkamp + - A severe bug in parsing the pixels section when an unknown character + is encountered. + +3.4j (96/12/31) + + ENHANCEMENTS: + - The XPM library can now be built under Amiga DOS. This entirely comes + from: Lorens Younes + See the README.AMIGA file for details. + - Changes for MSW: big performance improvement in ParseAndPutPixels(), + fixed creation of the mask in SetColor() + - patch from Jan Wielemaker + - makefiles are provided for VMS + - given by Martin P.J. Zinser m.zinser@gsi.de + - Imakefiles reworked to get smoother builds and fixes from: + - Paul DuBois dubois@primate.wisc.edu + - Larry Schwimmer schwim@cyclone.stanford.edu + - thanks to some code rearrangement the library is smaller (the size + reduction goes from 4 to 7% depending on the system) + + BUGS CORRECTED: + - A severe bug (introduced in 3.4i as part of the sprintf + optimization) in code writing XPM extensions to a buffer + XpmCreateBufferFromImage/Pixmap. + - The XpmAttributes definition in xpm.h was declaring nalloc_colors to + be Bool, it's an int. + +3.4i (96/09/13) + + NEW FEATURES: + - The XPM library now allows the application to pass its own color + allocation/free functions. For this matter the following was done: + The XpmAttributes structure has three new fields alloc_color, + free_color, and color_closure. The following new valuemasks were + added XpmAllocColorFunc, XpmFreeColorsFunc, XpmColorClosure. And + two new types were defined XpmAllocColorFunc and XpmFreeColorsFunc. + See documentation for details. + + ENHANCEMENTS: + - Windows NT support. It should compile and run fine based on the X + Consortium X11R6 distribution. + - The README file contains information to compile on Solaris with gcc. + - Part of the code has been optimized by using the value returned by + sprintf instead of calling strlen. Add the flag -DVOID_SPRINTF + if on your system sprintf returns void. + - patch from Thomas Ott thommy@rz.fh-augsburg.de + + BUGS CORRECTED: + - XpmFree is now a real function (simply calling free by default). + + CHANGES TO THE DOC: + - The documentation describes the new XpmAttributes fields and their + use. + +3.4h (96/02/01) + + NEW FEATURES: + - The XpmAttributes has a new member called 'alloc_close_colors' which + lets the caller specify whether close colors should be allocated + using XAllocColor or not. This is especially useful when one uses a + private colormap full of read/write cells. + The xpm.h header file define a new bitmap flag called + XpmAllocCloseColors to use along with this new slot. + - Dale Pease peased@bigbird.cso.gtegsc.com + - The XpmAttributes has a new member called 'bitmap_format' which lets + the caller specify the format of 1 bit depth images (XYBitmap or + ZPixmap). The xpm.h header file define a new bitmap flag called + XpmBitmapFormat to use along with this new field. + + ENHANCEMENTS: + - XpmReadFileTo[Image/Pixmap], XpmCreate[Image/Pixmap]FromData, + XpmCreateImageFromDataFromBuffer functions do no longer use a + temporary XpmImage object, which reduces a lot the amount of memory + used. On the other hand it can take a little more time, but given the + following figures (based on sxpm) it is a real good trade-off. + + Reading a 22x22 pixmap with 5 colors no time change is detected + using time: + real 0.3 + user 0.1 + sys 0.1 + + Reading a 1279x1023 pixmap with 14 colors (quite extreme case for + XPM!) the time goes from: + real 1.9 + user 0.8 + sys 0.8 + + to: + real 2.2 + user 1.8 + sys 0.3 + + Reading the 22x22 pixmap with 5 colors the memory usage (under + purify) goes from: + 255256 code + 55496 data/bss + 163848 heap (peak use) + 4248 stack + to: + 271240 code + 55472 data/bss + 159752 heap (peak use) + 4224 stack + + And reading the 1279x1023 pixmap with 14 colors it goes from: + 255256 code + 55496 data/bss + 6705160 heap (peak use) + 4280 stack + to: + 271240 code + 55472 data/bss + 1732616 heap (peak use) + 4264 stack + + This clearly shows that while for small pixmaps there is no real + difference on both sides, for large pixmaps this makes a huge + difference about the amount of memory used and it is not much + slower. + + Note that you can still get the old behavior using both + XpmReadFileToXpmImage and XpmCreate[Image/Pixmap]FromXpmImage instead + of XpmReadFileTo[Image/Pixmap]. Once more XPM gives you the choice! + + BUGS CORRECTED: + - when defined locally the global symbols strcasecmp and strdup are + now called xpmstrcasecmp and xpmstrdup to avoid any possible + conflict. + - VMS has a bogus file system which requires a work around in + XpmReadFileToBuffer. + - patch from Bob.Deen@jpl.nasa.gov + - the type of the exactColors attribute has been changed from unsigned + int to Bool. + + CHANGES TO THE DOC: + - the documentation describes the new XpmAttributes fields + alloc_close_colors and bitmap_format. + +3.4g (95/10/08) + + ENHANCEMENTS: + - The XpmAttributes structure has now two new slots: alloc_pixels and + nalloc_pixels in order to provide an easy way to free allocated + colors. The new bitmask XpmReturnAllocPixels should be used to + request this data through the valuemask. Unless you really know why, + you should use this instead of XpmReturnPixels, pixels, and npixels. + - the XPM1 format parsing has been improved. + - patch from Chuck Thompson + - compilers defining _STDC_ to something different from 1 are now + considered as ANSI compilers. + - the README file provides now more info on how to build XPM depending + on the system. + + BUGS CORRECTED: + - a bug introduced in 3.4f in the XPM1 format parsing function. + - fix from Chuck Thompson + - the hashtable was not free when the color parsing failed. + - patch from ackley@cs.unm.edu (David Ackley) + - the close color mechanism wasn't used if one of the closeness + parameter was null. Now only one needs to be different from 0. + Lorens Younes d93-hyo@nada.kth.se + - parsing of long comments failed with a segmentation fault. + + CHANGES TO THE DOC: + - the documentation describes the new XpmAttributes fields + alloc_pixels and nalloc_pixels and how they are used. + +3.4f (95/05/29) + + ENHANCEMENTS: + - Defines IMAKE_DEFINES in the top Imakefile so one can easily avoid + building the shared library. + - Add some information about the installation process in the README. + - filenames are surrounded with quotes when calling gzip or compress in + order to allow spaces within filenames. + - William Parn + - the compilation and the shared library building should be smoother + on Alpha OSF/1. + - patch from Dale Moore + + BUGS CORRECTED: + - a segmentation fault occurring in some weird case. + +3.4e (95/03/01) + + ENHANCEMENTS: + - The top Imakefile passes CDEBUGFLAGS and DEFINES to subdirs. Thus + only this Imakefile should need to be edited by users. + - FAQ includes the answer to the question "How can I get a non + rectangular icon using XPM ?" + - VMS support updated + - patch from Martin P.J. Zinser m.zinser@gsi.de + + BUGS CORRECTED: + - XpmCreateImageFromXpmImage() called from XpmReadFileToPixmap() could + lead to a segmentation fault since free was called on a memory block + size variable instead of the block itself. Note: this bug has been + introduced in 3.4d. + +3.4d (95/01/31) + + ENHANCEMENTS: + - sxpm now supports a -version option command. + + BUGS CORRECTED: + - the list of pixels returned in XpmAttributes was wrong when two + colors were defined as None in the read XPM + - Lionel.Mallet@sophia.inria.fr + - the parser was skipping whitespace reading extensions strings. This + has been fixed so extensions lines are now returned exactly as they + are. + - some compilation control added for the dec alpha with X11R5 (LONG64) + - patch from Fredrik Lundh + - when writing an XPM file, '-' characters are replaced with '_' + characters in the array name, in order to get a valid C syntax name. + - XYPixmap format images were not correctly handled. + - XPM1 file with names using multiple '_' characters are now handled + correctly. + - todd@erda.rl.af.mil (Todd Gleason) + +3.4c (94/06/06) + + Yes, this is kind of quick. But this is because no code has been modified, + this is just a new packaging to make the whole stuff more suitable to the + X development team's requests for inclusion in the R6 contrib. + + ENHANCEMENTS: + - Several filenames were too long to fit without any conflict on DOS + and CD-ROM filesystems. They have been renamed. + - Imakefiles use XCOMM for comments instead of the # character. + - the Postscript documentation file doc/xpm.ps is now distributed as + doc/xpm.PS.gz and allows browsing with tools such as ghostview. + - Besides, parts of lib/misc.c have been moved to several new files, + and some functions of data.c have been moved to other files in + order to get a better link profile. + - I've also added a FAQ hoping this will prevent people from + continuously filling my mailbox with the same questions. + - sxpm.c includes instead of "xpm.h" and BUILDINCTOP is + used in Makefiles as expected. + - Everything can be done simply using "xmkmf -a" and "make". + +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 retrieve 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 writing 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 function 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 writing 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 applications: + * 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 reorganized 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 initialization 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 behavior 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 standard 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 optional, 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 writing 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 algorithm 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 normally. + +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 monochrome 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/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..446fa4c --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1989-95 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/FAQ.html b/FAQ.html new file mode 100644 index 0000000..18d4ee6 --- /dev/null +++ b/FAQ.html @@ -0,0 +1,344 @@ + + + + +FAQ XPM + + + +

The XPM
+Frequently Asked Questions

+

+This article contains the answers to some Frequently Asked Questions about the +XPM format and/or library. If you don't find the answer to your problem here, +then you can mail either to lehors@sophia.inria.fr or to the mailing list +xpm-talk@sophia.inria.fr. + + +

Contents

+ +
    +
  1. How do I convert my images to or from XPM ? +
  2. Why are my XPM files said to be invalid ? +
  3. Why does my program core dumps using XPM ? +
  4. Why does my program core dumps using XPM with a widget ? +
  5. How can I get a non rectangular icon using XPM ? +
  6. What exactly triggers the creation of a mask when using XPM ? +
  7. How should I use the mask ? +
  8. Is there a string to pixmap converter somewhere ? +
  9. How can I edit XPM icons ? +
  10. Is there a collection of icons somewhere ? +
  11. The documentation fails to print out. Why ? +
  12. Copyright +
+ + +

1. How do I convert my images to or from XPM ?

+

+ Netpbm is surely the best image conversion package that I know of. It defines + formats for color, gray and monochrome images and provides a set of filters. + Thus a GIF image can be converted to XPM with something like: +

+ $ giftoppm youricon.gif | ppmtoxpm > youricon.xpm +

+ The latest release can be found at least from wuarchive.wustl.edu + (128.252.135.4), directory /graphics/graphics/packages/NetPBM + + +

2. Why are my XPM files said to be invalid ?

+

+ There are three official versions of the XPM format. The XPM library since + version 3.3 can read all them but writes out only XPM 3. Also the small + program called sxpm which is part of the XPM library package can be used to + automatically translate XPM 1 and 2 files to XPM 3 with a command such as: +

+ $ sxpm -nod yourxpm1or2file -o yourxpm3file +

+ Also, the XPM format defines "None" to be the color name meaning + "transparent", but IXI used to hack the XPM library in its early days to + handle transparency as "#Transparent". This makes IXI format not compatible + with the official XPM format, and so not readable neither by the official XPM + library nor any of the programs built on top of it. +

+ The only solutions are either to stick on IXI programs which can deal with + their format or convert your files to the standard XPM format. This can be + done simply by changing "#Transparent" to "None". + + +

3. Why does my program core dumps using XPM ?

+

+ Be sure the XpmAttributes structure you pass by reference has a valid + valuemask. You can give NULL instead if you don't want to use an + XpmAttributes but if you do, you MUST initialize its valuemask component to + some valid value, at least 0, otherwise unpredictable errors can occur. +

+ So instead of doing something like: +

+      XpmAttributes attrib;
+
+      XpmReadFileToPixmap(dpy, d, filename, &pixmap, &mask, &attrib);
+
+

+ you should do: +

+      XpmAttributes attrib;
+
+      attrib.valuemask = 0;
+      XpmReadFileToPixmap(dpy, d, filename, &pixmap, &mask, &attrib);
+
+ + +

4. Why does my program core dumps using XPM with a widget ?

+
    +
  • First the XPM library is Xlib level, so don't pass your widget as a + Drawable parameter. A Drawable is either a Window or a Pixmap. The widget's + window can do the job but: + +
  • Then a widget only gets a Window when realized, so passing XtWindow(widget) + with a not yet realized widget is wrong. Either realize you widget first or + use another window. Since the Drawable parameter is only used to specify + the screen to which the pixmap must be created on, most of the time the + default root window is just fine. +
+ + +

5. How can I get a non rectangular icon using XPM ?

+

+ The X Window System does not support transparent color. However there are + several ways you can use to get the same visual effect using XPM: +

    +
  • First you can use the None color to get a shape mask and use it as + explained below (question 7). + +
  • Second you can define a symbolic color name such as "mask" in the XPM + format file, then use the color overriding mechanism to set this symbolic + color to the color of the underlying object. Note that in this case the XPM + library won't create a shape mask, and that if the color of the underlying + object is changed then you'll have to create a new pixmap. +
+ + +

6. What exactly triggers the creation of a mask when using XPM ?

+

+ Basically a mask is created if "None" is used as one of the color of the + pixmap. Be aware that this is not only true if it is used in the XPM of the + pixmap since the colors can be overridden at load time. So a mask is created + if the "None" color is used at load time, coming either from the XPM + definition or the color overriding. + + +

7. How should I use the mask ?

+

+ There are basically two ways of using the mask: +

    +
  • Use the mask as a shapemask with the X11 Nonrectangular Saphe Window + Extension. Typically this is what should be done when the icon is used in a + desktop. + +
  • Use the mask as a clipmask in the GC you pass to XCopyArea when drawing the + pixmap. So the "transparent" pixels being not actually drawn will get the + underlying pixels colors. +
+ + +

8. Is there a string to pixmap converter for Motif ?

+

+ Yes, Motif 2.0 or later does support XPM pixmaps as well as XBM bitmaps. + + +

9. How can I edit XPM icons ?

+

+ As listed below several editors either commercial or not are supporting the + XPM format. However, pixmap is the one I would recommend since it is freely + available and, being fully dedicated to XPM, it allows to edit all the + special things, such as the symbolic color names, which makes XPM different + from all the other image formats. Pixmap can always be found by ftp from + ftp.x.org (contrib) and avahi.inria.fr (pub/pixmap). +

+Last Update: 3 August 1994 + + +
XPM Icon Editors
ProgramInfosSource/AuthorPlatformsSAXPMcost +
pixmap +Lionel Malletsourceyes3NC + +
pixt +J. Michael Flanerysourceyes1NC + +
pixed
    +
  • part of X.desktop +
  • current version doesn't work on 24-plane displays +
+
IXIMany UNIXno3N/A + +
olpixmap
    +
  • packaged with the OLIT (OpenLook) toolkit +
+
USLSun, SVR4.2, UnixWareno1N/A + +
xfedor
    +
  • only uses XLIB +
  • doesn't work on 24-plane displays +
+
Daniel Dardaillersourceyes3NC + +
SCOpaint
    +
  • included with the ODT package +
+
SCO/Wing EngODTyes2.8N/A + +
pme.icn
    +
  • written in the Icon language +
+
Icon Projectsourceyes3NC + +
PixEditT
    +
  • there is currently no support for editing the colormap +
+
Free Widget Foundationsourceyes3NC + +
xscribble +Robert Forsmansourceyes?NC + +
vueicon
    +
  • included with Vue3.0 +
+
Hewlett-PackardHPyes3N/A + +
iconedit V3 SunSoftSparc/Sun3yes2N/A + +
Pixmap Editor
    +
  • this is a Widget, not a complete program +
+
ICS?yes?? + +
ezX Sunrise Softwarey???N/A + +
XPaint
    +
  • full featured, works on all displays +
  • current release is 2.1.1 (last update January 1994) +
+
David Koblassourceyes3NC + +
Phoenix +ohtcolor@niksula.hut.fisourceyes3NC + +
pixed
    +
  • pixed is part of the TeleUSE UIMS +
  • More info is available from service@ignite.alsys.com +
+
AlsysMany UNIXyes3N/A + +
display +John Cristysourceyes3NC +
+ +

+SA - Stand Alone program
+NC - No Charge (i.e. free); most programs are copyrighted.
+XPM - XPM format supported
+source - built from source code; likely works on all standard X platforms
+N/A - icon editor is normally distributed with other software + +

+Send updates, additions, corrections, etc. to dan@bristol.com + + +

10. Is there a collection of icons somewhere ?

+

+ At least there is one freely available: Anthony's X Icon Library. You can + found it on several ftp servers, such as server.berkeley.edu/pub/AIcons. It + contains only small icons (less than about 100x100 pixels in size) which are + stored in groups in a logical way. Color icons are stored in XPM format and + Black & White icons in XBM. + + +

11. The documentation fails to print out. Why ?

+

+ The PostScript documentation file is formatted for US letter paper. Frame + Maker tries very hard to ensure that you have the right paper and punts if + you don't. However, you can easily work around this problem by applying the + following patch. If for some reason applying the patch fails, you can still + do it by hand. Just locate the corresponding block in the PS file and remove + the lines with a leading '-' character. + By the way, this applies to any doc generated by Frame Maker. The + corresponding block might be slightly different depending on which version of + Frame Maker was used, but it is still easy to locate. + +

+*** xpm.PS      Wed Sep 11 15:47:43 1996
+--- xpm-A4.PS   Thu Nov 21 09:27:28 1996
+***************
+*** 647,668 ****
+        0 ne /edown exch def 
+        /yscale exch def
+        /xscale exch def
+-       FMLevel1 {
+-               manualfeed {setmanualfeed} if
+-               /FMdicttop countdictstack 1 add def 
+-               /FMoptop count def 
+-               setpapername 
+-               manualfeed {true} {papersize} ifelse 
+-               {manualpapersize} {false} ifelse 
+-               {desperatepapersize} {false} ifelse 
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-               count -1 FMoptop {pop pop} for
+-               countdictstack -1 FMdicttop {pop end} for 
+-               }
+-               {{1 dict dup /PageSize [paperwidth paperheight]put setpagedevice}stopped
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-                {1 dict dup /ManualFeed manualfeed put setpagedevice } stopped pop }
+-       ifelse 
+        
+        FMPColor {
+                currentcolorscreen
+--- 647,652 ----
+
+ + +
+

Copyright (C) 1989-95 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. + + diff --git a/FILES b/FILES new file mode 100644 index 0000000..e1bf3fa --- /dev/null +++ b/FILES @@ -0,0 +1,68 @@ +CHANGES +COPYRIGHT +FAQ.html +FILES +Imakefile +Makefile.noX +README.html +README.AMIGA +README.MSW +namecvt +lib +lib/Imakefile +lib/Makefile.noX +lib/Makefile.AmigaGCC +lib/Smakefile +lib/Attrib.c +lib/CrBufFrI.c +lib/CrBufFrP.c +lib/CrDatFrI.c +lib/CrDatFrP.c +lib/CrIFrBuf.c +lib/CrIFrDat.c +lib/CrIFrP.c +lib/CrPFrBuf.c +lib/CrPFrDat.c +lib/CrPFrI.c +lib/Image.c +lib/Info.c +lib/RdFToBuf.c +lib/RdFToDat.c +lib/RdFToI.c +lib/RdFToP.c +lib/WrFFrBuf.c +lib/WrFFrDat.c +lib/WrFFrI.c +lib/WrFFrP.c +lib/amigax.h +lib/amigax.c +lib/create.c +lib/data.c +lib/descrip.mms +lib/hashtab.c +lib/make.com +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/XpmI.h +lib/Xpm-def.cpp +doc +doc/xpm.PS +sxpm +sxpm/Imakefile +sxpm/Makefile.noX +sxpm/plaid.xpm +sxpm/plaid_ext.xpm +sxpm/plaid_mask.xpm +sxpm/sxpm.c +sxpm/sxpm.man +cxpm +cxpm/Imakefile +cxpm/Makefile.noX +cxpm/cxpm.c +cxpm/cxpm.man diff --git a/README.AMIGA b/README.AMIGA new file mode 100644 index 0000000..7a40137 --- /dev/null +++ b/README.AMIGA @@ -0,0 +1,10 @@ +The XPM library for Amiga works best with AmigaOS 3.x, but will work +(with limited color support) with earlier OS versions too. It can be +compiled with both SAS/C and GCC (makefiles are included). + +All functions except the Xpm*Pixmap* functions are supported. + +I have also written some Amiga-specific utility functions (not +included). Contact me if you would like to have them too. + +-Lorens Younes (d93-hyo@nada.kth.se) diff --git a/README.MSW b/README.MSW new file mode 100644 index 0000000..f631525 --- /dev/null +++ b/README.MSW @@ -0,0 +1,127 @@ + +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 except the files related to Pixmap operations: *P*.c. +!!!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! + +================================================================ +Some fixes and comments by Jan Wielemaker (jan@swi.psy.uva.nl), +Oct 24, 1996: + + * Please try not to disturb me on this, XPM is not my + piece of cake. + + * Hermann Dunkel has appearently moved in virtual space. + +Changes: + + * I've used the xpm package under NT 4.0 and MSVC++ 4.2. + + * I've made a big performance improvement in + ParseAndPutPixels(), fixed creation of the mask in + SetColor() in create.c. I looked into XCreateImage() + in simx.c, but commented out my improvement for reasons + you'll find there. If you know what is going on, statement + (1) does not apply to you. + +Comments on installation: + + * Donot include the to/from pixmap files into the project. + These are the ones containing a capital P somewhere in their + name. You can also first include all, and then remove all + the files you get errors on :-) + + * The DC that is requested should be a valid memory DC, thus + CreateCompatibleDC(NULL) provides a good generic one, but + GetDC(NULL) doesn't! This costed me some time. + + * The real difficulty is using the mask, mostly due to the + bad documentation. If 95 or NT is your target, use: + + MaskBlt(context.hdc, // Destination DC + x, y, w, h, // Destination area + mhdc, // Memory DC with the image selected + sx, sy, // Source X,Y + msk, // HBITMAP of the mask + sx, sy, // Mask X,Y + MAKEROP4(SRCPAINT, SRCCOPY)); // The magic op code. +================================================================ + + +-- + ////|\\\\ \\\\\\ 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/README.html b/README.html new file mode 100644 index 0000000..6711f23 --- /dev/null +++ b/README.html @@ -0,0 +1,303 @@ + + + + +XPM README + + + +

XPM README

+ +

Contents

+ +
    +
  1. What Is XPM? +
  2. Where to get XPM? +
  3. Documentation +
  4. Installation +
      +
    1. With imake +
    2. Without imake +
    +
  5. SXPM +
  6. CXPM +
  7. Other Tools +
  8. Discussion +
  9. Copyright +
+ + +

1. 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 details. + + +

2. Where to get XPM?

+

+New XPM updates are announced on the comp.windows.x newsgroup, and on the +"xpm-talk" list and you can always consult the XPM Home page at http://www.inria.fr/koala/lehors/xpm.html +

The latest "official" XPM release can always be found at: +
Boston, USA: ftp://ftp.x.org/contrib +
Sophia Antipolis, France: ftp://koala.inria.fr/pub/xpm + + +

3. 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 (doc/xpm.PS) and has been produced with +FrameMaker. The source files are available on request. +

+A FAQ (Frequently Asked Questions) is also provided, +so if you experience any problem you should have a look at this file. + + +

4. Installation

+

+To obtain the XPM library, first uncompress and untar the compressed tar file +in an appropriate directory. +

+Then you can either compile XPM via "imake" or in a stand-alone way. + +

4.1. With imake

+

+ Imakefiles are provided to build both shared and unshared libraries. + However, building a shared lib is very OS dependent and often requires + specific files which are not available. Also config files are often not + set correctly for this task. So if it fails you can avoid trying to + build one and simply build the static library instead. In order to do + so you should edit the top Imakefile to add -DSharedLibXpm=NO to the + definition of IMAKE_DEFINES as described. +

+ The compilation and installation of the library and the sxpm program + should only require you to edit the top Imakefile. But you should do so + in order to specify the locations where the various files should be + installed and to set the DEFINES variable accordingly to your system. +

+ On Solaris 2.* the compilation works only in the native svr4 + environment, avoid the bsd one or it won't compile. Especially you + should be using /opt/SUNWspro/bin/cc and not /usr/ucb/cc. + Also since the compiler is no longer part of the OS distribution a lot + of people use gcc instead. This is fine, but be aware that the imake + tool you get as part of the X Window System on a solaris box is + configured for cc. Therefore the compilation using the generated + Makefiles will not succeed unless you have changed the default + configuration. An easy work around is to directly edit the generated + lib/Makefile to change '-K pic' to '-fpic'. Fixing your imake + configuration would be better though. +

+ On Linux, if you do not use ELF yet you'd better get the binary + distribution available from sunsite. Because it's really a pain to + build a shared lib and the current XPM distribution doesn't contain + the jump files you would need to do so. On the other hand people have + had no problems building it using ELF. +

+ Then execute the following command: +

+		xmkmf -a
+
+

+ or if this option is not supported by your version of xmkmf: +

+		xmkmf
+		make Makefiles
+		make includes
+		make depend		(optional)
+
+

+ Then simply execute: +

+		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 program and man page. +

+ If it fails, be sure you have set the DEFINES correctly in the top + Imakefile to suit your machine. + +

NOTE ON USING IMAKE:

+

+ Building the XPM distribution with imake requires to have imake + correctly installed and configured on your + system. I do my best at tweaking the Imakefiles so they work with + as many imake flavors people might have as possible but there is + nothing I can do against wrong imake configurations. So if your + build fails using imake, don't send me email for advice. Get your + imake configuration fixed or forget about it! + + +

4.2. Without imake

+

+ A set of makefiles is provided for those who do not have imake + available on their system. However, this is only provided as a + convenience and you should be considered as a starting point and not as + something ready to use. These makefiles, called Makefile.noX, will most + likely require some editing in order be set accordingly to your system. +

+ Once this setting is done, you should be able to compile XPM, by + executing the following command: +

+	        make -f Makefile.noX
+
+

+ Then to install it, do: +

+		make -f Makefile.noX install
+
+ + +

5. 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 already have it, 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 -plaid -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. + + +

6. CXPM

+

+The cxpm tool is provided to help you figure out whether an XPM file is correct +or not with regard to its format. If you have previously done 'make' or +'make all' you should already have it, otherwise just do: +

+		      cd cxpm; make
+
+

+The related man page will tell you everything about it but here is a simple +example of what it does: +

+$ ./cxpm bogus_pixmap
+Xpm Error: Invalid XPM file.
+Error found line 3 near character 5
+
+

+It is pretty limited but at least, unlike sxpm, it gives you some hint on where +the error occured within the file. + + +

7. 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. + +

8. 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. +The archive of the xpm-talk list is available through the web at +http://zenon.inria.fr/koala/xpm-talk-hypermail +and through ftp at ftp://koala.inria.fr/pub/xpm/xpm-talk-archive +

+Please mail any bug reports or modifications done, comments, suggestions, +requests for updates or patches to port on another machine to: + +

Email: lehors@sophia.inria.fr +
Phone: +33 (0)4 93 65 78 89 +
Surface Mail:
+Arnaud Le Hors
+Inria BP.93
+2004, Route des lucioles
+06902 Sophia Antipolis Cedex
+FRANCE + + +


+

Copyright (C) 1989-95 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. + diff --git a/cxpm/cxpm.c b/cxpm/cxpm.c new file mode 100644 index 0000000..20b4905 --- /dev/null +++ b/cxpm/cxpm.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 1998 Arnaud LE HORS + * + * 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 + * Arnaud LE HORS 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 Arnaud LE HORS shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Arnaud LE HORS. + */ +/* $XFree86: xc/extras/Xpm/cxpm/cxpm.c,v 1.2 2001/08/01 00:44:34 tsi Exp $ */ + +/*****************************************************************************\ +* cxpm.c: * +* * +* Check XPM File program * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#define CXPMPROG + +#include "../lib/XpmI.h" + +#undef xpmGetC +#define xpmGetC(data) sGetc(data, data->stream.file) +#define Getc sGetc +#define Ungetc sUngetc + + +/* + * special getc and ungetc counting read lines and characters + * note that 's' could stand both for "special" and "slow" ;-) + */ +static int +sGetc(data) + xpmData *data; +{ + int c = getc(data->stream.file); + if (c == '\n') { + data->lineNum++; + data->charNum = 0; + } else { + data->charNum++; + } + return c; +} + +static void +sUngetc(data, c) + xpmData *data; + int c; +{ + ungetc(c, data->stream.file); + if (c == '\n') { + data->lineNum--; + data->charNum = 0; + } else { + data->charNum--; + } +} + +/* include all the code we need (yeah, I know, quite ugly...) */ +#include "../lib/data.c" +#include "../lib/parse.c" +#include "../lib/RdFToI.c" /* only for OpenReadFile and xpmDataClose */ +#include "../lib/hashtab.c" +#include "../lib/misc.c" +#include "../lib/Attrib.c" +#include "../lib/Image.c" + +void +ErrorMessage(ErrorStatus, data) + int ErrorStatus; + xpmData *data; + +{ + char *error = NULL; + + switch (ErrorStatus) { + case XpmSuccess: + return; + case XpmOpenFailed: + error = "Cannot open file"; + break; + case XpmFileInvalid: + error = "Invalid XPM file"; + break; + case XpmNoMemory: + error = "Not enough memory"; + break; + case XpmColorFailed: + error = "Failed to parse color"; + break; + } + + if (error) { + fprintf(stderr, "Xpm Error: %s.\n", error); + if (ErrorStatus == XpmFileInvalid && data) + fprintf(stderr, "Error found line %d near character %d\n", + data->lineNum + 1, + data->charNum + 1); + exit(1); + } +} + +int +main(argc, argv) + int argc; + char **argv; +{ + XpmImage image; + char *filename; + int ErrorStatus; + xpmData data; + + if (argc > 1) { + if (!strcmp(argv[1], "-?") || !strncmp(argv[1], "-h", 2)) { + fprintf(stderr, "Usage: %s [filename]\n", argv[0]); + exit(1); + } + filename = argv[1]; + } else { + filename = NULL; + } + + xpmInitXpmImage(&image); + + if ((ErrorStatus = OpenReadFile(filename, &data)) != XpmSuccess) + ErrorMessage(ErrorStatus, NULL); + + ErrorStatus = xpmParseData(&data, &image, NULL); + ErrorMessage(ErrorStatus, &data); + + xpmDataClose(&data); + XpmFreeXpmImage(&image); + + exit(0); +} diff --git a/cxpm/cxpm.man b/cxpm/cxpm.man new file mode 100644 index 0000000..21d63fd --- /dev/null +++ b/cxpm/cxpm.man @@ -0,0 +1,49 @@ +.\"Copyright (C) 1998 Arnaud LE HORS +.\" +.\"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 +.\"Arnaud LE HORS 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 Arnaud LE HORS shall not be +.\"used in advertising or otherwise to promote the sale, use or other dealings +.\"in this Software without prior written authorization from Arnaud LE HORS. +.\" +.nr )S 12 +.TH CXPM 1 +.PD +.ad b +.SH NAME +cxpm \- Check an XPM (X PixMap) file - XPM 1, 2, or 3. +.SH SYNOPSIS +\fBcxpm\fR +[\|\fIfilename\fP\|] +.SH DESCRIPTION +.PP +The \fBcxpm\fP program can be used to check the format of any XPM (version 1, 2, +or 3) file. On error, unlike \fBsxpm\fR, \fBcxpm\fR prints out an error message +indicating where the parser choked. This should help finding out what's wrong +with an XPM file but do not expect too much from it though. This is not even +close from being some kind of lint program for XPM. First, it stops at the +first error it encounters - so several fix and retry cycles may be necessary to +get your file to parse successfully. Second, \fBcxpm\fP only cares about +the format. If, for instance, your pixmap uses too many colors for your system +you still may experience difficulties displaying it. Be warned. +.PP +When no \fIfilename\fP is given \fBcxpm\fR reads from the standard input. +.SH AUTHOR +Arnaud Le Hors (lehors@sophia.inria.fr) +.br +Copyright (C) 1998 by Arnaud LE HORS. diff --git a/include/X11/xpm.h b/include/X11/xpm.h new file mode 100644 index 0000000..786f3c3 --- /dev/null +++ b/include/X11/xpm.h @@ -0,0 +1,502 @@ +/* + * Copyright (C) 1989-95 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. + */ +/* $XFree86: xc/extras/Xpm/lib/xpm.h,v 1.2 2001/08/22 23:36:44 dawes Exp $ */ + +/*****************************************************************************\ +* 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 + */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +#ifndef XPM_h +#define XPM_h + +/* + * first some identification numbers: + * the version and revision numbers are 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 from these numbers. + */ +#define XpmFormat 3 +#define XpmVersion 4 +#define XpmRevision 11 +#define XpmIncludeVersion ((XpmFormat * 100 + XpmVersion) * 100 + XpmRevision) + +#ifndef XPM_NUMBERS + +#ifdef FOR_MSW +# define SYSV /* uses memcpy string.h etc. */ +# include +# include "simx.h" /* defines some X stuff using MSW types */ +#define NEED_STRCASECMP /* at least for MSVC++ */ +#else /* FOR_MSW */ +# ifdef AMIGA +# include "amigax.h" +# else /* not AMIGA */ +# include +# include +# endif /* not AMIGA */ +#endif /* FOR_MSW */ + +/* 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 + +/* make sure we know whether function prototypes are needed or not */ +#ifndef NeedFunctionPrototypes +# if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) +# define NeedFunctionPrototypes 1 +# else +# define NeedFunctionPrototypes 0 +# endif +#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 + +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 int (*XpmAllocColorFunc)( +#if NeedFunctionPrototypes + Display* /* display */, + Colormap /* colormap */, + char* /* colorname */, + XColor* /* xcolor */, + void* /* closure */ +#endif +); + +typedef int (*XpmFreeColorsFunc)( +#if NeedFunctionPrototypes + Display* /* display */, + Colormap /* colormap */, + Pixel* /* pixels */, + int /* npixels */, + void* /* closure */ +#endif +); + +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 used pixels */ + XpmColorSymbol *colorsymbols; /* List 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; /* List of extensions */ + + unsigned int ncolors; /* Number of colors */ + XpmColor *colorTable; /* List of colors */ +/* 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; /* Color table index of transparent + color */ + + /* Color Allocation Directives */ + Bool 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 */ + + Pixel *alloc_pixels; /* Returns the list of alloc'ed color + pixels */ + int nalloc_pixels; /* Returns the number of alloc'ed + color pixels */ + + Bool alloc_close_colors; /* Specify whether close colors should + be allocated using XAllocColor + or not */ + int bitmap_format; /* Specify the format of 1bit depth + images: ZPixmap or XYBitmap */ + + /* Color functions */ + XpmAllocColorFunc alloc_color; /* Application color allocator */ + XpmFreeColorsFunc free_colors; /* Application color de-allocator */ + void *color_closure; /* Application private data to pass to + alloc_color and free_colors */ + +} 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 + +#define XpmReturnAllocPixels (1L<<16) +#define XpmAllocCloseColors (1L<<17) +#define XpmBitmapFormat (1L<<18) + +#define XpmAllocColor (1L<<19) +#define XpmFreeColors (1L<<20) +#define XpmColorClosure (1L<<21) + + +/* 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 XpmI.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 + + +/* macros for forward declarations of functions with prototypes */ +#if NeedFunctionPrototypes +#define FUNC(f, t, p) extern t f p +#define LFUNC(f, t, p) static t f p +#else +#define FUNC(f, t, p) extern t f() +#define LFUNC(f, t, p) static t f() +#endif + + +/* + * functions declarations + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* FOR_MSW, all ..Pixmap.. are excluded, only the ..XImage.. are used */ +/* Same for Amiga! */ + +#if !defined(FOR_MSW) && !defined(AMIGA) + 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 + + 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)); +#if !defined(FOR_MSW) && !defined(AMIGA) + 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 + 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, (void)); + 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, (void)); + + /* XpmImage functions */ + FUNC(XpmReadFileToXpmImage, int, (char *filename, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmWriteFileFromXpmImage, int, (char *filename, + XpmImage *image, + XpmInfo *info)); +#if !defined(FOR_MSW) && !defined(AMIGA) + 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)); +#if !defined(FOR_MSW) && !defined(AMIGA) + 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)); + + FUNC(XpmGetParseError, int, (char *filename, + int *linenum_return, + int *charnum_return)); + + FUNC(XpmFree, void, (void *ptr)); + +#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/Attrib.c b/src/Attrib.c new file mode 100644 index 0000000..04b843b --- /dev/null +++ b/src/Attrib.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* Attrib.c: * +* * +* XPM library * +* Functions related to the XpmAttributes structure * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +/* 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(ct, ncolors, oldct) + 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(colorTable, ncolors) + 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(colorTable, ncolors) + 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(extensions, nextensions) + 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(attributes) + 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 */ + if (attributes->valuemask & XpmReturnExtensions) { + attributes->extensions = NULL; + attributes->nextensions = 0; + } + if (attributes->valuemask & XpmReturnAllocPixels) { + attributes->alloc_pixels = NULL; + attributes->nalloc_pixels = 0; + } + } +} + +/* + * Fill in the XpmAttributes with the XpmImage and the XpmInfo + */ +void +xpmSetAttributes(attributes, image, info) + 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(attributes) + 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; + } + if (attributes->valuemask & XpmReturnAllocPixels + && attributes->nalloc_pixels) { + XpmFree(attributes->alloc_pixels); + attributes->alloc_pixels = NULL; + attributes->nalloc_pixels = 0; + } + attributes->valuemask = 0; +} diff --git a/src/CrBufFrI.c b/src/CrBufFrI.c new file mode 100644 index 0000000..da6735f --- /dev/null +++ b/src/CrBufFrI.c @@ -0,0 +1,401 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrBufFrI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM buffer * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/CrBufFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */ + +#include "XpmI.h" + +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, buffer_return, image, shapeimage, attributes) + 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) \ +{ \ + ErrorStatus = status; \ + goto error; \ +} + +int +XpmCreateBufferFromXpmImage(buffer_return, image, info) + 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 */ +#ifndef VOID_SPRINTF + used_size = +#endif + sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n"); +#ifdef VOID_SPRINTF + used_size = strlen(buf); +#endif + 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) { +#ifndef VOID_SPRINTF + used_size += +#endif + sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt); +#ifdef VOID_SPRINTF + used_size += strlen(info->hints_cmt) + 5; +#endif + } +#ifndef VOID_SPRINTF + l = +#endif + sprintf(buf, "\"%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + + if (info && (info->valuemask & XpmHotspot)) { +#ifndef VOID_SPRINTF + l += +#endif + sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + } + if (extensions) { +#ifndef VOID_SPRINTF + l += +#endif + sprintf(buf + l, " XPMEXT"); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + } +#ifndef VOID_SPRINTF + l += +#endif + sprintf(buf + l, "\",\n"); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + 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) { +#ifndef VOID_SPRINTF + used_size += +#endif + sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt); +#ifdef VOID_SPRINTF + used_size += strlen(info->colors_cmt) + 5; +#endif + } + 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 need, realloc the data + * 4 = 1 (for '"') + 3 (for '",\n') + * 1 = - 2 (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) { +#ifndef VOID_SPRINTF + used_size += +#endif + sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt); +#ifdef VOID_SPRINTF + used_size += strlen(info->pixels_cmt) + 5; +#endif + } + 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 */ + strcpy(ptr + used_size, "};\n"); + + *buffer_return = ptr; + + return (XpmSuccess); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (ptr) + XpmFree(ptr); + return (ErrorStatus); +} + +static int +WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp) + 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)) { +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + } + } + strcpy(s, "\",\n"); + l = s + 3 - 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(dataptr, used_size, width, height, cpp, pixels, colors) + 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(ext, num) + 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(dataptr, used_size, ext, num) + 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++) { +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, ",\n\"XPMEXT %s\"", ext->name); +#ifdef VOID_SPRINTF + s += strlen(ext->name) + 11; +#endif + a = ext->nlines; + for (y = 0, line = ext->lines; y < a; y++, line++) { +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, ",\n\"%s\"", *line); +#ifdef VOID_SPRINTF + s += strlen(*line) + 4; +#endif + } + } + strcpy(s, ",\n\"XPMENDEXT\""); + *used_size += s - dataptr + 13; +} + +static int +CommentsSize(info) + 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/CrBufFrP.c b/src/CrBufFrP.c new file mode 100644 index 0000000..4aec4fb --- /dev/null +++ b/src/CrBufFrP.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrBufFrP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM buffer * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmCreateBufferFromPixmap(display, buffer_return, pixmap, shapemask, + attributes) + 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); +} diff --git a/src/CrDatFrI.c b/src/CrDatFrI.c new file mode 100644 index 0000000..71fac8b --- /dev/null +++ b/src/CrDatFrI.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrDataFI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/CrDatFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */ + +#include "XpmI.h" + +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, data_return, image, shapeimage, attributes) + 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) \ +{ \ + ErrorStatus = status; \ + goto exit; \ +} + +int +XpmCreateDataFromXpmImage(data_return, image, info) + 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; +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, "%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + + if (info && (info->valuemask & XpmHotspot)) { +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + } + if (extensions) { + strcpy(s, " XPMEXT"); + s += 7; + } + l = s - 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; + ErrorStatus = XpmSuccess; + +/* exit point, free only locally allocated variables */ +exit: + if (header) { + for (l = 0; l < header_nlines; l++) + if (header[l]) + XpmFree(header[l]); + XpmFree(header); + } + return(ErrorStatus); +} + +static int +CreateColors(dataptr, data_size, colors, ncolors, cpp) + 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)) { +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + } + } + l = s - buf + 1; + s = (char *) XpmMalloc(l); + if (!s) + return (XpmNoMemory); + *data_size += l; + *dataptr = strcpy(s, buf); + } + return (XpmSuccess); +} + +static void +CreatePixels(dataptr, width, height, cpp, pixels, colors) + 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(ext, num, ext_size, ext_nlines) + 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(dataptr, offset, ext, num, ext_nlines) + 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/CrDatFrP.c b/src/CrDatFrP.c new file mode 100644 index 0000000..1593b7b --- /dev/null +++ b/src/CrDatFrP.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrDataFP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmCreateDataFromPixmap(display, data_return, pixmap, shapemask, attributes) + 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); +} diff --git a/src/CrIFrBuf.c b/src/CrIFrBuf.c new file mode 100644 index 0000000..ba863ac --- /dev/null +++ b/src/CrIFrBuf.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrIFrBuf.c: * +* * +* XPM library * +* Parse an Xpm buffer (file in memory) and create the image and possibly its * +* mask * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +LFUNC(OpenBuffer, void, (char *buffer, xpmData *mdata)); + +int +XpmCreateImageFromBuffer(display, buffer, image_return, + shapeimage_return, attributes) + Display *display; + char *buffer; + XImage **image_return; + XImage **shapeimage_return; + XpmAttributes *attributes; +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + xpmData mdata; + + xpmInitXpmImage(&image); + xpmInitXpmInfo(&info); + + /* open buffer to read */ + OpenBuffer(buffer, &mdata); + + /* create the XImage from the XpmData */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, &info, attributes); + } else + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, NULL, attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmCreateXpmImageFromBuffer(buffer, image, info) + char *buffer; + XpmImage *image; + XpmInfo *info; +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open buffer to read */ + OpenBuffer(buffer, &mdata); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + return (ErrorStatus); +} + +/* + * open the given buffer to be read or written as an xpmData which is returned + */ +static void +OpenBuffer(buffer, mdata) + char *buffer; + xpmData *mdata; +{ + mdata->type = XPMBUFFER; + mdata->cptr = buffer; + mdata->CommentLength = 0; +} diff --git a/src/CrIFrDat.c b/src/CrIFrDat.c new file mode 100644 index 0000000..f3c19c7 --- /dev/null +++ b/src/CrIFrDat.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrIFrData.c: * +* * +* XPM library * +* Parse an Xpm array and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +LFUNC(OpenArray, void, (char **data, xpmData *mdata)); + +int +XpmCreateImageFromData(display, data, image_return, + shapeimage_return, attributes) + Display *display; + char **data; + XImage **image_return; + XImage **shapeimage_return; + XpmAttributes *attributes; +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + xpmData mdata; + + xpmInitXpmImage(&image); + xpmInitXpmInfo(&info); + + /* open data */ + OpenArray(data, &mdata); + + /* create an XpmImage from the file */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, &info, attributes); + } else + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, NULL, attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmCreateXpmImageFromData(data, image, info) + char **data; + XpmImage *image; + XpmInfo *info; +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open data */ + OpenArray(data, &mdata); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + return (ErrorStatus); +} + +/* + * open the given array to be read or written as an xpmData which is returned + */ +static void +OpenArray(data, mdata) + 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 */ +} diff --git a/src/CrIFrP.c b/src/CrIFrP.c new file mode 100644 index 0000000..f8aa4ed --- /dev/null +++ b/src/CrIFrP.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrIFrP.c: * +* * +* XPM library * +* Create the XImage related to the given Pixmap. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +void +xpmCreateImageFromPixmap(display, pixmap, ximage_return, width, height) + 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); +} diff --git a/src/CrPFrBuf.c b/src/CrPFrBuf.c new file mode 100644 index 0000000..19e7cb9 --- /dev/null +++ b/src/CrPFrBuf.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrPFrBuf.c: * +* * +* XPM library * +* Parse an Xpm buffer and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmCreatePixmapFromBuffer(display, d, buffer, pixmap_return, + shapemask_return, attributes) + 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); +} diff --git a/src/CrPFrDat.c b/src/CrPFrDat.c new file mode 100644 index 0000000..fcbe5f1 --- /dev/null +++ b/src/CrPFrDat.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrPFrData.c: * +* * +* XPM library * +* Parse an Xpm array and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmCreatePixmapFromData(display, d, data, pixmap_return, + shapemask_return, attributes) + 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); +} diff --git a/src/CrPFrI.c b/src/CrPFrI.c new file mode 100644 index 0000000..0661a4e --- /dev/null +++ b/src/CrPFrI.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* CrPFrI.c: * +* * +* XPM library * +* Create the Pixmap related to the given XImage. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +void +xpmCreatePixmapFromImage(display, d, ximage, pixmap_return) + Display *display; + Drawable d; + XImage *ximage; + Pixmap *pixmap_return; +{ + GC gc; + XGCValues values; + + *pixmap_return = XCreatePixmap(display, d, ximage->width, + ximage->height, ximage->depth); + /* set fg and bg in case we have an XYBitmap */ + values.foreground = 1; + values.background = 0; + gc = XCreateGC(display, *pixmap_return, + GCForeground | GCBackground, &values); + + XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0, + ximage->width, ximage->height); + + XFreeGC(display, gc); +} diff --git a/src/Image.c b/src/Image.c new file mode 100644 index 0000000..0753622 --- /dev/null +++ b/src/Image.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* Image.c: * +* * +* XPM library * +* Functions to init and free the XpmImage structure. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +/* + * Init returned data to free safely later on + */ +void +xpmInitXpmImage(image) + XpmImage *image; +{ + image->ncolors = 0; + image->colorTable = NULL; + image->data = NULL; +} + +/* + * Free the XpmImage data which have been allocated + */ +void +XpmFreeXpmImage(image) + XpmImage *image; +{ + if (image->colorTable) + xpmFreeColorTable(image->colorTable, image->ncolors); + if (image->data) + XpmFree(image->data); + image->data = NULL; +} diff --git a/src/Info.c b/src/Info.c new file mode 100644 index 0000000..9bc41c8 --- /dev/null +++ b/src/Info.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* Info.c: * +* * +* XPM library * +* Functions related to the XpmInfo structure. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +/* + * Init returned data to free safely later on + */ +void +xpmInitXpmInfo(info) + 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(info) + 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(info, attributes) + 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(info, attributes) + 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; + } +} diff --git a/src/RdFToBuf.c b/src/RdFToBuf.c new file mode 100644 index 0000000..898a9fc --- /dev/null +++ b/src/RdFToBuf.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* RdFToBuf.c: * +* * +* XPM library * +* Copy a file to a malloc'ed buffer, provided as a convenience. * +* * +* 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 "XpmI.h" +#include +#if !defined(FOR_MSW) && !defined(WIN32) +#include +#endif +#ifndef VAX11C +#include +#endif +#if defined(FOR_MSW) || defined(WIN32) +#include +#define stat _stat +#define fstat _fstat +#define fdopen _fdopen +#define O_RDONLY _O_RDONLY +#endif + +int +XpmReadFileToBuffer(filename, buffer_return) + char *filename; + char **buffer_return; +{ + int fd, fcheck, len; + char *ptr; + struct stat stats; + FILE *fp; + + *buffer_return = NULL; + +#ifndef VAX11C + fd = open(filename, O_RDONLY); +#else + fd = open(filename, O_RDONLY, NULL); +#endif + 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, 1, len, fp); + fclose(fp); +#ifdef VMS + /* VMS often stores text files in a variable-length record format, + where there are two bytes of size followed by the record. fread + converts this so it looks like a record followed by a newline. + Unfortunately, the size reported by fstat() (and fseek/ftell) + counts the two bytes for the record terminator, while fread() + counts only one. So, fread() sees fewer bytes in the file (size + minus # of records) and thus when asked to read the amount + returned by stat(), it fails. + The best solution, suggested by DEC, seems to consider the length + returned from fstat() as an upper bound and call fread() with + a record length of 1. Then don't check the return value. + We'll check for 0 for gross error that's all. + */ + len = fcheck; + if (fcheck == 0) { +#else + if (fcheck != len) { +#endif + XpmFree(ptr); + return XpmOpenFailed; + } + ptr[len] = '\0'; + *buffer_return = ptr; + return XpmSuccess; +} diff --git a/src/RdFToDat.c b/src/RdFToDat.c new file mode 100644 index 0000000..4bb28fc --- /dev/null +++ b/src/RdFToDat.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* RdFToDat.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 "XpmI.h" + +int +XpmReadFileToData(filename, data_return) + 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/RdFToI.c b/src/RdFToI.c new file mode 100644 index 0000000..867d656 --- /dev/null +++ b/src/RdFToI.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* RdFToI.c: * +* * +* XPM library * +* Parse an XPM file and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/RdFToI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */ + +#include "XpmI.h" +#include +#if !defined(NO_ZPIPE) && defined(WIN32) +# define popen _popen +# define pclose _pclose +# if defined(STAT_ZFILE) +# include +# define stat _stat +# define fstat _fstat +# endif +#endif + +LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata)); +LFUNC(xpmDataClose, void, (xpmData *mdata)); + +#ifndef CXPMPROG +int +XpmReadFileToImage(display, filename, + image_return, shapeimage_return, attributes) + Display *display; + char *filename; + XImage **image_return; + XImage **shapeimage_return; + XpmAttributes *attributes; +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + xpmData mdata; + + xpmInitXpmImage(&image); + xpmInitXpmInfo(&info); + + /* open file to read */ + if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* create the XImage from the XpmData */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, &info, attributes); + } else + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, NULL, attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + + xpmDataClose(&mdata); + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmReadFileToXpmImage(filename, image, info) + char *filename; + XpmImage *image; + XpmInfo *info; +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open file to read */ + if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} +#endif /* CXPMPROG */ + +/* + * open the given file to be read as an xpmData which is returned. + */ +static int +OpenReadFile(filename, mdata) + char *filename; + xpmData *mdata; +{ +#ifndef NO_ZPIPE + char buf[BUFSIZ]; +# ifdef STAT_ZFILE + char *compressfile; + struct stat status; +# endif +#endif + + if (!filename) { + mdata->stream.file = (stdin); + mdata->type = XPMFILE; + } else { +#ifndef NO_ZPIPE + int len = strlen(filename); + if ((len > 2) && !strcmp(".Z", filename + (len - 2))) { + mdata->type = XPMPIPE; + sprintf(buf, "uncompress -c \"%s\"", filename); + if (!(mdata->stream.file = popen(buf, "r"))) + return (XpmOpenFailed); + + } else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) { + mdata->type = XPMPIPE; + sprintf(buf, "gunzip -qc \"%s\"", filename); + if (!(mdata->stream.file = popen(buf, "r"))) + return (XpmOpenFailed); + + } else { +# ifdef STAT_ZFILE + if (!(compressfile = (char *) XpmMalloc(len + 4))) + return (XpmNoMemory); + + sprintf(compressfile, "%s.Z", filename); + 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 { + sprintf(compressfile, "%s.gz", filename); + 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 +#endif + if (!(mdata->stream.file = fopen(filename, "r"))) { +#if !defined(NO_ZPIPE) && defined(STAT_ZFILE) + XpmFree(compressfile); +#endif + return (XpmOpenFailed); + } + mdata->type = XPMFILE; +#ifndef NO_ZPIPE +# ifdef STAT_ZFILE + } + } + XpmFree(compressfile); +# endif + } +#endif + } + mdata->CommentLength = 0; +#ifdef CXPMPROG + mdata->lineNum = 0; + mdata->charNum = 0; +#endif + return (XpmSuccess); +} + +/* + * close the file related to the xpmData if any + */ +static void +xpmDataClose(mdata) + xpmData *mdata; +{ + switch (mdata->type) { + case XPMFILE: + if (mdata->stream.file != (stdin)) + fclose(mdata->stream.file); + break; +#ifndef NO_ZPIPE + case XPMPIPE: + pclose(mdata->stream.file); + break; +#endif + } +} diff --git a/src/RdFToP.c b/src/RdFToP.c new file mode 100644 index 0000000..212d260 --- /dev/null +++ b/src/RdFToP.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* RdFToP.c: * +* * +* XPM library * +* Parse an XPM file and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmReadFileToPixmap(display, d, filename, pixmap_return, + shapemask_return, attributes) + 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); +} diff --git a/src/WrFFrBuf.c b/src/WrFFrBuf.c new file mode 100644 index 0000000..3ed6685 --- /dev/null +++ b/src/WrFFrBuf.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* WrFFrBuf.c: * +* * +* XPM library * +* Write a memory buffer to a file, provided as a convenience. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmWriteFileFromBuffer(filename, buffer) + 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; +} diff --git a/src/WrFFrDat.c b/src/WrFFrDat.c new file mode 100644 index 0000000..bfaa909 --- /dev/null +++ b/src/WrFFrDat.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* WrFFrData.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 "XpmI.h" + +int +XpmWriteFileFromData(filename, data) + 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/WrFFrI.c b/src/WrFFrI.c new file mode 100644 index 0000000..0769f80 --- /dev/null +++ b/src/WrFFrI.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* WrFFrI.c: * +* * +* XPM library * +* Write an image and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/WrFFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +#include "XpmI.h" +#if !defined(NO_ZPIPE) && defined(WIN32) +# define popen _popen +# define pclose _pclose +#endif + +/* MS Windows define a function called WriteFile @#%#&!!! */ +LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, char *name, + XpmInfo *info)); + +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)); + +LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata)); +LFUNC(xpmDataClose, void, (xpmData *mdata)); + +int +XpmWriteFileFromImage(display, filename, image, shapeimage, attributes) + 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(filename, image, info) + char *filename; + XpmImage *image; + XpmInfo *info; +{ + xpmData mdata; + char *name, *dot, *s, new_name[BUFSIZ]; + int ErrorStatus; + + /* open file to write */ + if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* figure out a name */ + if (filename) { +#ifdef VMS + name = filename; +#else + if (!(name = rindex(filename, '/')) +#ifdef AMIGA + && !(name = rindex(filename, ':')) +#endif + ) + name = filename; + else + name++; +#endif + /* let's try to make a valid C syntax name */ + if (index(name, '.')) { + strcpy(new_name, name); + /* change '.' to '_' */ + name = s = new_name; + while ((dot = index(s, '.'))) { + *dot = '_'; + s = dot; + } + } + if (index(name, '-')) { + if (name != new_name) { + strcpy(new_name, name); + name = new_name; + } + /* change '-' to '_' */ + s = name; + while ((dot = index(s, '-'))) { + *dot = '_'; + s = dot; + } + } + } else + name = "image_name"; + + /* write the XpmData from the XpmImage */ + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} + +static int +xpmWriteFile(file, image, name, info) + FILE *file; + XpmImage *image; + char *name; + XpmInfo *info; +{ + /* calculation variables */ + unsigned int cmts, extensions; + int ErrorStatus; + + 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, colors, ncolors) + 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, width, height, cpp, pixels, colors) + 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, ext, num) + 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\""); +} + +/* + * open the given file to be written as an xpmData which is returned + */ +static int +OpenWriteFile(filename, mdata) + char *filename; + xpmData *mdata; +{ +#ifndef NO_ZPIPE + char buf[BUFSIZ]; + +#endif + + if (!filename) { + mdata->stream.file = (stdout); + mdata->type = XPMFILE; + } else { +#ifndef NO_ZPIPE + int len = strlen(filename); + if (len > 2 && !strcmp(".Z", filename + (len - 2))) { + sprintf(buf, "compress > \"%s\"", filename); + if (!(mdata->stream.file = popen(buf, "w"))) + return (XpmOpenFailed); + + mdata->type = XPMPIPE; + } else if (len > 3 && !strcmp(".gz", filename + (len - 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; +#ifndef NO_ZPIPE + } +#endif + } + return (XpmSuccess); +} + +/* + * close the file related to the xpmData if any + */ +static void +xpmDataClose(mdata) + xpmData *mdata; +{ + switch (mdata->type) { + case XPMFILE: + if (mdata->stream.file != (stdout)) + fclose(mdata->stream.file); + break; +#ifndef NO_ZPIPE + case XPMPIPE: + pclose(mdata->stream.file); + break; +#endif + } +} diff --git a/src/WrFFrP.c b/src/WrFFrP.c new file mode 100644 index 0000000..b78ea0c --- /dev/null +++ b/src/WrFFrP.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* WrFFrP.c: * +* * +* XPM library * +* Write a pixmap and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "XpmI.h" + +int +XpmWriteFileFromPixmap(display, filename, pixmap, shapemask, attributes) + 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); +} diff --git a/src/XpmI.h b/src/XpmI.h new file mode 100644 index 0000000..237a535 --- /dev/null +++ b/src/XpmI.h @@ -0,0 +1,314 @@ +/* + * Copyright (C) 1989-95 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. + */ +/* $XFree86: xc/extras/Xpm/lib/XpmI.h,v 1.8 2002/01/07 19:40:23 dawes Exp $ */ + +/*****************************************************************************\ +* XpmI.h: * +* * +* XPM library * +* Internal Include file * +* * +* ** Everything defined here is subject to changes any time. ** * +* * +* 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 XPMI_h +#define XPMI_h + +#include "xpm.h" + +/* + * lets try to solve include files + */ + +#include +#include +/* stdio.h doesn't declare popen on a Sequent DYNIX OS */ +#ifdef sequent +extern FILE *popen(); +#endif + +#include +#include + +#ifdef VMS +#include +#include +#endif + +/* The following should help people wanting to use their own memory allocation + * functions. To avoid the overhead of a function call when the standard + * functions are used these are all macros, even the XpmFree function which + * needs to be a real function for the outside world though. + * So if change these be sure to change the XpmFree function in misc.c + * accordingly. + */ +#define XpmFree(ptr) free(ptr) + +#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 + +#define XPMMAXCMTLEN BUFSIZ +typedef struct { + unsigned int type; + union { + FILE *file; + char **data; + } stream; + char *cptr; + unsigned int line; + int CommentLength; + char Comment[XPMMAXCMTLEN]; + char *Bcmt, *Ecmt, Bos, Eos; + int format; /* 1 if XPM1, 0 otherwise */ +#ifdef CXPMPROG + int lineNum; + int charNum; +#endif +} 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 internal routines */ + +FUNC(xpmParseData, int, (xpmData *data, XpmImage *image, XpmInfo *info)); +FUNC(xpmParseDataAndCreate, int, (Display *display, xpmData *data, + XImage **image_return, + XImage **shapeimage_return, + XpmImage *image, XpmInfo *info, + XpmAttributes *attributes)); + +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)); + +#if !defined(FOR_MSW) && !defined(AMIGA) +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 + +/* 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 *)(long)i) +#define HashColorIndex(slot) ((unsigned long)((*slot)->data)) +#define USE_HASHTABLE (cpp > 2 && ncolors > 4) + +/* 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(xpmParseHeader, int, (xpmData *mdata)); +FUNC(xpmParseValues, 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)); + +FUNC(xpmParseColors, int, (xpmData *data, unsigned int ncolors, + unsigned int cpp, XpmColor **colorTablePtr, + xpmHashTable *hashtable)); + +FUNC(xpmParseExtensions, int, (xpmData *data, XpmExtension **extensions, + unsigned int *nextensions)); + +/* 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 + +#ifndef AMIGA +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) +#endif /* not AMIGA */ + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +#ifdef NEED_STRDUP +FUNC(xpmstrdup, char *, (char *s1)); +#else +#undef xpmstrdup +#define xpmstrdup strdup +#endif + +#ifdef NEED_STRCASECMP +FUNC(xpmstrcasecmp, int, (char *s1, char *s2)); +#else +#undef xpmstrcasecmp +#define xpmstrcasecmp strcasecmp +#endif + +FUNC(xpmatoui, unsigned int, + (char *p, unsigned int l, unsigned int *ui_return)); + +#endif diff --git a/src/amigax.c b/src/amigax.c new file mode 100644 index 0000000..aa82d49 --- /dev/null +++ b/src/amigax.c @@ -0,0 +1,382 @@ +/* + * Copyright (C) 19896 Lorens Younes + * + * 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 + * Lorens Younes 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 Lorens Younes shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Lorens Younes. + */ + +/*****************************************************************************\ +* amigax.c: * +* * +* XPM library * +* Emulates some Xlib functionality for Amiga. * +* * +* Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 * +* Revised 4/96 * +\*****************************************************************************/ + +#include "XpmI.h" +#include "amigax.h" + +#include +#include + +#include + + +static struct RastPort * +AllocRastPort (unsigned int, unsigned int, unsigned int); +static void +FreeRastPort (struct RastPort *, unsigned int,unsigned int); + + +static struct RastPort * +AllocRastPort ( + unsigned int width, + unsigned int height, + unsigned int depth) +{ + struct RastPort *rp; + + rp = XpmMalloc (sizeof (*rp)); + if (rp != NULL) + { + InitRastPort (rp); + if (GfxBase->LibNode.lib_Version >= 39) + { + rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL); + if (rp->BitMap == NULL) + { + FreeRastPort (rp, width, height); + return NULL; + } + } + else + { + unsigned int i; + + rp->BitMap = XpmMalloc (sizeof (*rp->BitMap)); + if (rp->BitMap == NULL) + { + FreeRastPort (rp, width, height); + return NULL; + } + + InitBitMap (rp->BitMap, depth, width, height); + for (i = 0; i < depth; ++i) + rp->BitMap->Planes[i] = NULL; + for (i = 0; i < depth; ++i) + { + rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height); + if (rp->BitMap->Planes[i] == NULL) + { + FreeRastPort (rp, width, height); + return NULL; + } + } + } + } + + return rp; +} + + +static void +FreeRastPort ( + struct RastPort *rp, + unsigned int width, + unsigned int height) +{ + if (rp != NULL) + { + if (rp->BitMap != NULL) + { + WaitBlit (); + if (GfxBase->LibNode.lib_Version >= 39) + FreeBitMap (rp->BitMap); + else + { + unsigned int i; + + for (i = 0; i < rp->BitMap->Depth; ++i) + { + if (rp->BitMap->Planes[i] != NULL) + FreeRaster (rp->BitMap->Planes[i], width, height); + } + XpmFree (rp->BitMap); + } + } + XpmFree (rp); + } +} + + +XImage * +AllocXImage ( + unsigned int width, + unsigned int height, + unsigned int depth) +{ + XImage *img; + + img = XpmMalloc (sizeof (*img)); + if (img != NULL) + { + img->width = width; + img->height = height; + img->rp = AllocRastPort (img->width, img->height, depth); + if (img->rp == NULL) + { + FreeXImage (img); + return NULL; + } + } + + return img; +} + + +int +FreeXImage ( + XImage *ximage) +{ + if (ximage != NULL) + { + FreeRastPort (ximage->rp, ximage->width, ximage->height); + XpmFree (ximage); + } + + return Success; +} + + +int +XPutPixel ( + XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + SetAPen (ximage->rp, pixel); + WritePixel (ximage->rp, x, y); + + return Success; +} + + +Status +AllocBestPen ( + Colormap colormap, + XColor *screen_in_out, + unsigned long precision, + Bool fail_if_bad) +{ + if (GfxBase->LibNode.lib_Version >= 39) + { + unsigned long r, g, b; + + r = screen_in_out->red * 0x00010001; + g = screen_in_out->green * 0x00010001; + b = screen_in_out->blue * 0x00010001; + screen_in_out->pixel = ObtainBestPen (colormap, r, g, b, + OBP_Precision, precision, + OBP_FailIfBad, fail_if_bad, + TAG_DONE); + if (screen_in_out->pixel == -1) + return False; + + QueryColor (colormap, screen_in_out); + } + else + { + XColor nearest, trial; + long nearest_delta, trial_delta; + int num_cells, i; + + num_cells = colormap->Count; + nearest.pixel = 0; + QueryColor (colormap, &nearest); + nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8)) + * ((screen_in_out->red >> 8) - (nearest.red >> 8))) + + + (((screen_in_out->green >> 8) - (nearest.green >> 8)) + * ((screen_in_out->green >> 8) - (nearest.green >> 8))) + + + (((screen_in_out->blue >> 8) - (nearest.blue >> 8)) + * ((screen_in_out->blue >> 8) - (nearest.blue >> 8)))); + for (i = 1; i < num_cells; i++) + { + /* precision and fail_if_bad is ignored under pre V39 */ + trial.pixel = i; + QueryColor (colormap, &trial); + trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8)) + * ((screen_in_out->red >> 8) - (trial.red >> 8))) + + + (((screen_in_out->green >> 8) - (trial.green >> 8)) + * ((screen_in_out->green >> 8) - (trial.green >> 8))) + + + (((screen_in_out->blue >> 8) - (trial.blue >> 8)) + * ((screen_in_out->blue >> 8) - (trial.blue >> 8)))); + if (trial_delta < nearest_delta) + { + nearest = trial; + nearest_delta = trial_delta; + } + } + screen_in_out->pixel = nearest.pixel; + screen_in_out->red = nearest.red; + screen_in_out->green = nearest.green; + screen_in_out->blue = nearest.blue; + } + + return True; +} + + +int +FreePens ( + Colormap colormap, + unsigned long *pixels, + int npixels) +{ + if (GfxBase->LibNode.lib_Version >= 39) + { + int i; + + for (i = 0; i < npixels; i++) + ReleasePen (colormap, pixels[i]); + } + + return Success; +} + + +Status +ParseColor ( + char *spec, + XColor *exact_def_return) +{ + int spec_length; + + if (spec == 0) + return False; + + spec_length = strlen(spec); + if (spec[0] == '#') + { + int hexlen; + char hexstr[10]; + + hexlen = (spec_length - 1) / 3; + if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1) + return False; + + hexstr[hexlen] = '\0'; + strncpy (hexstr, spec + 1, hexlen); + exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); + strncpy (hexstr, spec + 1 + hexlen, hexlen); + exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); + strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen); + exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); + + return True; + } + else + { + FILE *rgbf; + int items, red, green, blue; + char line[512], name[512]; + Bool success = False; + + rgbf = fopen ("LIBS:rgb.txt", "r"); + if (rgbf == NULL) + return False; + + while (fgets(line, sizeof (line), rgbf) && !success) + { + items = sscanf (line, "%d %d %d %[^\n]\n", + &red, &green, &blue, name); + if (items != 4) + continue; + + if (red < 0 || red > 0xFF + || green < 0 || green > 0xFF + || blue < 0 || blue > 0xFF) + { + continue; + } + + if (0 == xpmstrcasecmp (spec, name)) + { + exact_def_return->red = red * 0x0101; + exact_def_return->green = green * 0x0101; + exact_def_return->blue = blue * 0x0101; + success = True; + } + } + fclose (rgbf); + + return success; + } +} + + +int +QueryColor ( + Colormap colormap, + XColor *def_in_out) +{ + if (GfxBase->LibNode.lib_Version >= 39) + { + unsigned long rgb[3]; + + GetRGB32 (colormap, def_in_out->pixel, 1, rgb); + def_in_out->red = rgb[0] >> 16; + def_in_out->green = rgb[1] >> 16; + def_in_out->blue = rgb[2] >> 16; + } + else + { + unsigned short rgb; + + rgb = GetRGB4 (colormap, def_in_out->pixel); + def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111; + def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111; + def_in_out->blue = (rgb & 0xF) * 0x1111; + } + + return Success; +} + + +int +QueryColors ( + Colormap colormap, + XColor *defs_in_out, + int ncolors) +{ + int i; + + for (i = 0; i < ncolors; i++) + QueryColor (colormap, &defs_in_out[i]); + + return Success; +} diff --git a/src/amigax.h b/src/amigax.h new file mode 100644 index 0000000..213ed76 --- /dev/null +++ b/src/amigax.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 1996 Lorens Younes + * + * 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 + * Lorens Younes 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 Lorens Younes shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Lorens Younes. + */ + +/*****************************************************************************\ +* amigax.h: * +* * +* XPM library * +* Emulates some Xlib functionality for Amiga. * +* * +* Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 * +* Revised 4/96 * +\*****************************************************************************/ + +#ifndef AMIGA_X +#define AMIGA_X + + +#include + +#include +#include + + +#define Success 0 + +/* really never used */ +#define ZPixmap 2 + +#define Bool int +#define Status int +#define True 1 +#define False 0 + +typedef struct ColorMap *Colormap; + +typedef void *Visual; + +typedef struct { + int width, height; + struct RastPort *rp; +} XImage; + +typedef struct { + unsigned long pixel; + unsigned short red, green, blue; +} XColor; + +typedef struct Screen Display; + + +#define XGrabServer(dpy) (Forbid ()) +#define XUngrabServer(dpy) (Permit ()) + +#define XDefaultScreen(dpy) (0) +#define XDefaultVisual(dpy, scr) (NULL) +#define XDefaultColormap(dpy, scr) (dpy->ViewPort.ColorMap) +#define XDefaultDepth(dpy, scr) (dpy->RastPort.BitMap->Depth) + +#define XCreateImage(dpy, vi, depth, format, offset, data, width, height, pad, bpl) \ + (AllocXImage (width, height, depth)) +#define XDestroyImage(img) (FreeXImage (img)) + +#define XAllocColor(dpy, cm, xc) \ + (AllocBestPen (cm, xc, PRECISION_EXACT, True)) +#define XFreeColors(dpy, cm, pixels, npixels, planes) \ + (FreePens (cm, pixels, npixels)) +#define XParseColor(dpy, cm, spec, exact_def_return) \ + (ParseColor (spec, exact_def_return)) +#define XQueryColor(dpy, cm, def_in_out) \ + (QueryColor(cm, def_in_out)) +#define XQueryColors(dpy, cm, defs_in_out, ncolors) \ + (QueryColors(cm, defs_in_out, ncolors)) + + +XImage * +AllocXImage ( + unsigned int width, + unsigned int height, + unsigned int depth); + + +int +FreeXImage ( + XImage *ximage); + + +int +XPutPixel ( + XImage *ximage, + int x, + int y, + unsigned long pixel); + + +Status +AllocBestPen ( + Colormap colormap, + XColor *screen_in_out, + unsigned long precision, + Bool fail_if_bad); + + +int +FreePens ( + Colormap colormap, + unsigned long *pixels, + int npixels); + + +Status +ParseColor ( + char *spec, + XColor *exact_def_return); + + +int +QueryColor ( + Colormap colormap, + XColor *def_in_out); + + +int +QueryColors ( + Colormap colormap, + XColor *defs_in_out, + int ncolors); + + +#endif /* AMIGA_X */ diff --git a/src/create.c b/src/create.c new file mode 100644 index 0000000..770fbf8 --- /dev/null +++ b/src/create.c @@ -0,0 +1,2484 @@ +/* + * Copyright (C) 1989-95 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 XpmImage. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/create.c,v 1.3 2002/01/07 19:40:49 dawes Exp $ */ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +#include "XpmI.h" +#include + +LFUNC(xpmVisualType, int, (Visual *visual)); + +LFUNC(AllocColor, int, (Display *display, Colormap colormap, + char *colorname, XColor *xcolor, void *closure)); +LFUNC(FreeColors, int, (Display *display, Colormap colormap, + Pixel *pixels, int n, void *closure)); + +#ifndef FOR_MSW +LFUNC(SetCloseColor, int, (Display *display, Colormap colormap, + Visual *visual, XColor *col, + Pixel *image_pixel, Pixel *mask_pixel, + Pixel *alloc_pixels, unsigned int *nalloc_pixels, + XpmAttributes *attributes, XColor *cols, int ncols, + XpmAllocColorFunc allocColor, void *closure)); +#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 *alloc_pixels, unsigned int *nalloc_pixels, + Pixel *used_pixels, unsigned int *nused_pixels, + XpmAttributes *attributes, XColor *cols, int ncols, + XpmAllocColorFunc allocColor, void *closure)); + +LFUNC(CreateXImage, int, (Display *display, Visual *visual, + unsigned int depth, int format, unsigned int width, + unsigned int height, XImage **image_return)); + +LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes, + XpmColor *colors, unsigned int ncolors, + Pixel *image_pixels, Pixel *mask_pixels, + unsigned int *mask_pixel_index, + Pixel *alloc_pixels, unsigned int *nalloc_pixels, + Pixel *used_pixels, unsigned int *nused_pixels)); + +#ifndef FOR_MSW +LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, + XImage *image, Pixel *image_pixels, + XImage *mask, Pixel *mask_pixels)); +#else /* FOR_MSW */ +LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, + XImage *image, Pixel *image_pixels, + XImage *mask, Pixel *mask_pixels)); +#endif + +#ifndef FOR_MSW +# ifndef AMIGA +/* XImage pixel routines */ +LFUNC(PutImagePixels, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); + +# else /* AMIGA */ +LFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); +# endif/* AMIGA */ +#else /* FOR_MSW */ +/* FOR_MSW pixel routine */ +LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image, + unsigned int width, unsigned int height, + unsigned int *pixelindex, Pixel *pixels)); +#endif /* FOR_MSW */ + +#ifdef NEED_STRCASECMP +FUNC(xpmstrcasecmp, int, (char *s1, char *s2)); + +/* + * in case strcasecmp is not provided by the system here is one + * which does the trick + */ +int +xpmstrcasecmp(s1, s2) + register char *s1, *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 *visual; +{ +#ifndef FOR_MSW +# ifndef AMIGA + switch (visual->class) { + 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 + /* set the key explicitly in the XpmAttributes to override this */ + return (XPM_COLOR); +# endif +#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); +} + + +/* default AllocColor function: + * call XParseColor if colorname is given, return negative value if failure + * call XAllocColor and return 0 if failure, positive otherwise + */ +static int +AllocColor(display, colormap, colorname, xcolor, closure) + Display *display; + Colormap colormap; + char *colorname; + XColor *xcolor; + void *closure; /* not used */ +{ + int status; + if (colorname) + if (!XParseColor(display, colormap, colorname, xcolor)) + return -1; + status = XAllocColor(display, colormap, xcolor); + return status != 0 ? 1 : 0; +} + + +#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, colormap, visual, col, image_pixel, mask_pixel, + alloc_pixels, nalloc_pixels, attributes, cols, ncols, + allocColor, closure) + Display *display; + Colormap colormap; + Visual *visual; + XColor *col; + Pixel *image_pixel, *mask_pixel; + Pixel *alloc_pixels; + unsigned int *nalloc_pixels; + XpmAttributes *attributes; + XColor *cols; + int ncols; + XpmAllocColorFunc allocColor; + void *closure; +{ + + /* + * 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; + Bool alloc_color; + + 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; + } + if (attributes && (attributes->valuemask & XpmAllocCloseColors)) + alloc_color = attributes->alloc_close_colors; + else + alloc_color = True; + + /* + * 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 (alloc_color) { + if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){ + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + *image_pixel = cols[c].pixel; + *mask_pixel = 1; + alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel; + return (0); + } else { + ++i; + if (i == ncols) + break; + c = closenesses[i].cols_index; + } + } else { + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + *image_pixel = cols[c].pixel; + *mask_pixel = 1; + return (0); + } + } + + /* 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 ((*allocColor)(display, colormap, NULL, col, closure)) { + *image_pixel = col->pixel; + *mask_pixel = 1; + alloc_pixels[(*nalloc_pixels)++] = col->pixel; + return (0); + } else { /* colormap has probably changed, so + * re-read... */ + if (n == ITERATIONS - 1) + XGrabServer(display); + +#if 0 + if (visual->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, colormap, visual, colorname, color_index, + image_pixel, mask_pixel, mask_pixel_index, + alloc_pixels, nalloc_pixels, used_pixels, nused_pixels, + attributes, cols, ncols, allocColor, closure) + Display *display; + Colormap colormap; + Visual *visual; + char *colorname; + unsigned int color_index; + Pixel *image_pixel, *mask_pixel; + unsigned int *mask_pixel_index; + Pixel *alloc_pixels; + unsigned int *nalloc_pixels; + Pixel *used_pixels; + unsigned int *nused_pixels; + XpmAttributes *attributes; + XColor *cols; + int ncols; + XpmAllocColorFunc allocColor; + void *closure; +{ + XColor xcolor; + int status; + + if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) { + status = (*allocColor)(display, colormap, colorname, &xcolor, closure); + if (status < 0) /* parse color failed */ + return (1); + + if (status == 0) { +#ifndef FOR_MSW + if (USE_CLOSECOLOR) + return (SetCloseColor(display, colormap, visual, &xcolor, + image_pixel, mask_pixel, + alloc_pixels, nalloc_pixels, + attributes, cols, ncols, + allocColor, closure)); + else +#endif /* ndef FOR_MSW */ + return (1); + } else + alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel; + *image_pixel = xcolor.pixel; +#ifndef FOR_MSW + *mask_pixel = 1; +#else + *mask_pixel = RGB(0,0,0); +#endif + used_pixels[(*nused_pixels)++] = xcolor.pixel; + } else { + *image_pixel = 0; +#ifndef FOR_MSW + *mask_pixel = 0; +#else + *mask_pixel = RGB(255,255,255); +#endif + /* store the color table index */ + *mask_pixel_index = color_index; + } + return (0); +} + + +static int +CreateColors(display, attributes, colors, ncolors, image_pixels, mask_pixels, + mask_pixel_index, alloc_pixels, nalloc_pixels, + used_pixels, nused_pixels) + Display *display; + XpmAttributes *attributes; + XpmColor *colors; + unsigned int ncolors; + Pixel *image_pixels; + Pixel *mask_pixels; + unsigned int *mask_pixel_index; + Pixel *alloc_pixels; + unsigned int *nalloc_pixels; + Pixel *used_pixels; + unsigned int *nused_pixels; +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + XpmColorSymbol *colorsymbols = NULL; + unsigned int numsymbols; + XpmAllocColorFunc allocColor; + void *closure; + + char *colorname; + unsigned int color, key; + Bool pixel_defined; + XpmColorSymbol *symbol = NULL; + 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); + + if (attributes && (attributes->valuemask & XpmAllocColor)) + allocColor = attributes->alloc_color; + else + allocColor = AllocColor; + if (attributes && (attributes->valuemask & XpmColorClosure)) + closure = attributes->color_closure; + else + closure = NULL; + +#ifndef FOR_MSW + if (USE_CLOSECOLOR) { + /* originally from SetCloseColor */ +#if 0 + if (visual->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; + +#ifndef AMIGA + ncols = visual->map_entries; +#else + ncols = colormap->Count; +#endif + 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 (color = 0; color < ncolors; color++, colors++, + image_pixels++, mask_pixels++) { + colorname = NULL; + pixel_defined = False; + defaults = (char **) colors; + + /* + * look for a defined symbol + */ + if (numsymbols) { + + unsigned int n; + + s = defaults[1]; + for (n = 0, symbol = colorsymbols; n < numsymbols; n++, 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 && + !xpmstrcasecmp(symbol->value, defaults[def_index])) + break; + } + } + if (n != numsymbols) { + if (symbol->name && symbol->value) + colorname = symbol->value; + else + pixel_defined = True; + } + } + if (!pixel_defined) { /* pixel not given as symbol value */ + + unsigned int k; + + if (colorname) { /* colorname given as symbol value */ + if (!SetColor(display, colormap, visual, colorname, color, + image_pixels, mask_pixels, mask_pixel_index, + alloc_pixels, nalloc_pixels, used_pixels, + nused_pixels, attributes, cols, ncols, + allocColor, closure)) + pixel_defined = True; + else + ErrorStatus = XpmColorError; + } + k = key; + while (!pixel_defined && k > 1) { + if (defaults[k]) { + if (!SetColor(display, colormap, visual, defaults[k], + color, image_pixels, mask_pixels, + mask_pixel_index, alloc_pixels, + nalloc_pixels, used_pixels, nused_pixels, + attributes, cols, ncols, + allocColor, closure)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + k--; + } + k = key + 1; + while (!pixel_defined && k < NKEYS + 1) { + if (defaults[k]) { + if (!SetColor(display, colormap, visual, defaults[k], + color, image_pixels, mask_pixels, + mask_pixel_index, alloc_pixels, + nalloc_pixels, used_pixels, nused_pixels, + attributes, cols, ncols, + allocColor, closure)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + k++; + } + if (!pixel_defined) { + if (cols) + XpmFree(cols); + return (XpmColorFailed); + } + } else { + /* simply use the given pixel */ + *image_pixels = symbol->pixel; + /* the following makes the mask to be built even if none + is given a particular pixel */ + if (symbol->value + && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) { + *mask_pixels = 0; + *mask_pixel_index = color; + } else + *mask_pixels = 1; + used_pixels[(*nused_pixels)++] = *image_pixels; + } + } + if (cols) + XpmFree(cols); + return (ErrorStatus); +} + + +/* default FreeColors function, simply call XFreeColors */ +static int +FreeColors(display, colormap, pixels, n, closure) + Display *display; + Colormap colormap; + Pixel *pixels; + int n; + void *closure; /* not used */ +{ + return XFreeColors(display, colormap, pixels, n, 0); +} + + +/* function call in case of error */ +#undef RETURN +#define RETURN(status) \ +{ \ + ErrorStatus = status; \ + goto error; \ +} + +int +XpmCreateImageFromXpmImage(display, image, + image_return, shapeimage_return, attributes) + 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; + int bitmap_format; + XpmFreeColorsFunc freeColors; + void *closure; + + /* variables to return */ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int mask_pixel_index = XpmUndefPixel; + int ErrorStatus; + + /* calculation variables */ + Pixel *image_pixels = NULL; + Pixel *mask_pixels = NULL; + Pixel *alloc_pixels = NULL; + Pixel *used_pixels = NULL; + unsigned int nalloc_pixels = 0; + unsigned int nused_pixels = 0; + + /* 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)); + + if (attributes && (attributes->valuemask & XpmBitmapFormat)) + bitmap_format = attributes->bitmap_format; + else + bitmap_format = ZPixmap; + + if (attributes && (attributes->valuemask & XpmFreeColors)) + freeColors = attributes->free_colors; + else + freeColors = FreeColors; + if (attributes && (attributes->valuemask & XpmColorClosure)) + closure = attributes->color_closure; + else + closure = NULL; + + ErrorStatus = XpmSuccess; + + /* malloc pixels index tables */ + image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!image_pixels) + return (XpmNoMemory); + + mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!mask_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!alloc_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!used_pixels) + RETURN(XpmNoMemory); + + /* get pixel colors, store them in index tables */ + ErrorStatus = CreateColors(display, attributes, image->colorTable, + image->ncolors, image_pixels, mask_pixels, + &mask_pixel_index, alloc_pixels, &nalloc_pixels, + used_pixels, &nused_pixels); + + if (ErrorStatus != XpmSuccess + && (ErrorStatus < 0 || (attributes + && (attributes->valuemask & XpmExactColors) + && attributes->exactColors))) + RETURN(ErrorStatus); + + /* create the ximage */ + if (image_return) { + ErrorStatus = CreateXImage(display, visual, depth, + (depth == 1 ? bitmap_format : ZPixmap), + image->width, image->height, &ximage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#ifndef FOR_MSW +# ifndef AMIGA + + /* + * set the ximage data using optimized functions for ZPixmap + */ + + if (ximage->bits_per_pixel == 8) + PutImagePixels8(ximage, image->width, image->height, + image->data, image_pixels); + else if (((ximage->bits_per_pixel | ximage->depth) == 1) && + (ximage->byte_order == ximage->bitmap_bit_order)) + PutImagePixels1(ximage, image->width, image->height, + image->data, image_pixels); + else if (ximage->bits_per_pixel == 16) + PutImagePixels16(ximage, image->width, image->height, + image->data, image_pixels); + else if (ximage->bits_per_pixel == 32) + PutImagePixels32(ximage, image->width, image->height, + image->data, image_pixels); + else + PutImagePixels(ximage, image->width, image->height, + image->data, image_pixels); +# else /* AMIGA */ + APutImagePixels(ximage, image->width, image->height, + image->data, image_pixels); +# endif +#else /* FOR_MSW */ + MSWPutImagePixels(display, ximage, image->width, image->height, + image->data, image_pixels); +#endif + } + /* create the shape mask image */ + if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { + ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, + image->width, image->height, &shapeimage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#ifndef FOR_MSW +# ifndef AMIGA + PutImagePixels1(shapeimage, image->width, image->height, + image->data, mask_pixels); +# else /* AMIGA */ + APutImagePixels(shapeimage, image->width, image->height, + image->data, mask_pixels); +# endif +#else /* FOR_MSW */ + MSWPutImagePixels(display, shapeimage, image->width, image->height, + image->data, mask_pixels); +#endif + + } + XpmFree(image_pixels); + XpmFree(mask_pixels); + + /* if requested return used pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnPixels || +/* 3.2 backward compatibility code */ + attributes->valuemask & XpmReturnInfos)) { +/* end 3.2 bc */ + attributes->pixels = used_pixels; + attributes->npixels = nused_pixels; + attributes->mask_pixel = mask_pixel_index; + } else + XpmFree(used_pixels); + + /* if requested return alloc'ed pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { + attributes->alloc_pixels = alloc_pixels; + attributes->nalloc_pixels = nalloc_pixels; + } else + XpmFree(alloc_pixels); + + /* return created images */ + if (image_return) + *image_return = ximage; + if (shapeimage_return) + *shapeimage_return = shapeimage; + + return (ErrorStatus); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + if (image_pixels) + XpmFree(image_pixels); + if (mask_pixels) + XpmFree(mask_pixels); + if (nalloc_pixels) + (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); + if (alloc_pixels) + XpmFree(alloc_pixels); + if (used_pixels) + XpmFree(used_pixels); + + return (ErrorStatus); +} + + +/* + * Create an XImage with its data + */ +static int +CreateXImage(display, visual, depth, format, width, height, image_return) + Display *display; + Visual *visual; + unsigned int depth; + int format; + 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, format, 0, 0, + width, height, bitmap_pad, 0); + if (!*image_return) + return (XpmNoMemory); + +#if !defined(FOR_MSW) && !defined(AMIGA) + /* 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 and AMIGA XCreateImage has done it all */ +#endif + return (XpmSuccess); +} + +#ifndef FOR_MSW +# ifndef AMIGA +/* + * 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(bpt, nb) + register unsigned char *bpt; + register int nb; +{ + do { + *bpt = _reverse_byte[*bpt]; + bpt++; + } while (--nb > 0); + return 0; +} + + +void +xpm_xynormalizeimagebits(bp, img) + 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(bp, img) + 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(src, dstoffset, numbits, 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 +PutImagePixels(image, width, height, pixelindex, pixels) + 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 + */ + +#if !defined(WORD64) && !defined(LONG64) +/* 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 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 +PutImagePixels32(image, width, height, pixelindex, pixels) + 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; +#if !defined(WORD64) && !defined(LONG64) + 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)]; + *((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; +#if !defined(WORD64) && !defined(LONG64) + if (*((char *) &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 +PutImagePixels16(image, width, height, pixelindex, pixels) + 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 +PutImagePixels8(image, width, height, pixelindex, pixels) + 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 +PutImagePixels1(image, width, height, pixelindex, pixels) + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + if (image->byte_order != image->bitmap_bit_order) + PutImagePixels(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, d, image, + pixmap_return, shapemask_return, attributes) + 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 /* AMIGA */ + +static void +APutImagePixels ( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + unsigned int *data = pixelindex; + unsigned int x, y; + unsigned char *array; + XImage *tmp_img; + BOOL success = FALSE; + + array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array)); + if (array != NULL) + { + tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, + image->rp->BitMap->Depth); + if (tmp_img != NULL) + { + for (y = 0; y < height; ++y) + { + for (x = 0; x < width; ++x) + array[x] = pixels[*(data++)]; + WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp); + } + FreeXImage (tmp_img); + success = TRUE; + } + XpmFree (array); + } + + if (!success) + { + for (y = 0; y < height; ++y) + for (x = 0; x < width; ++x) + XPutPixel (image, x, y, pixels[*(data++)]); + } +} + +# endif/* AMIGA */ +#else /* FOR_MSW part follows */ +static void +MSWPutImagePixels(dc, image, width, height, pixelindex, pixels) + Display *dc; + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + unsigned int *data = pixelindex; + unsigned int x, y; + HBITMAP obm; + + obm = SelectObject(*dc, image->bitmap); + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */ + } + } + SelectObject(*dc, obm); +} + +#endif /* FOR_MSW */ + + + +#if !defined(FOR_MSW) && !defined(AMIGA) + +static int +PutPixel1(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + register char *src; + register char *dst; + register int i; + Pixel px; + int nbytes; + + for (i=0, px=pixel; i>=8) + ((unsigned char *)&pixel)[i] = px; + src = &ximage->data[XYINDEX(x, y, ximage)]; + dst = (char *)&px; + px = 0; + nbytes = ximage->bitmap_unit >> 3; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + XYNORMALIZE(&px, ximage); + i = ((x + ximage->xoffset) % ximage->bitmap_unit); + _putbits ((char *)&pixel, i, 1, (char *)&px); + XYNORMALIZE(&px, ximage); + src = (char *) &px; + dst = &ximage->data[XYINDEX(x, y, ximage)]; + for (i = nbytes; --i >= 0; ) + *dst++ = *src++; + + return 1; +} + +static int +PutPixel(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + register char *src; + register char *dst; + register int i; + Pixel px; + int nbytes, ibpp; + + ibpp = ximage->bits_per_pixel; + if (ximage->depth == 4) + pixel &= 0xf; + for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &ximage->data[ZINDEX(x, y, ximage)]; + dst = (char *) &px; + px = 0; + nbytes = (ibpp + 7) >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, ximage); + _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); + ZNORMALIZE(&px, ximage); + src = (char *) &px; + dst = &ximage->data[ZINDEX(x, y, ximage)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + + return 1; +} + +static int +PutPixel32(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; + *((unsigned long *)addr) = pixel; + return 1; +} + +static int +PutPixel32MSB(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; + addr[0] = pixel >> 24; + addr[1] = pixel >> 16; + addr[2] = pixel >> 8; + addr[3] = pixel; + return 1; +} + +static int +PutPixel32LSB(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; + addr[3] = pixel >> 24; + addr[2] = pixel >> 16; + addr[1] = pixel >> 8; + addr[0] = pixel; + return 1; +} + +static int +PutPixel16MSB(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; + addr[0] = pixel >> 8; + addr[1] = pixel; + return 1; +} + +static int +PutPixel16LSB(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; + addr[1] = pixel >> 8; + addr[0] = pixel; + return 1; +} + +static int +PutPixel8(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + ximage->data[ZINDEX8(x, y, ximage)] = pixel; + return 1; +} + +static int +PutPixel1MSB(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + if (pixel & 1) + ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7); + else + ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7)); + return 1; +} + +static int +PutPixel1LSB(ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + if (pixel & 1) + ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7); + else + ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7)); + return 1; +} + +#endif /* not FOR_MSW && not AMIGA */ + +/* + * This function parses an Xpm file or data and directly create an XImage + */ +int +xpmParseDataAndCreate(display, data, image_return, shapeimage_return, + image, info, attributes) + Display *display; + xpmData *data; + XImage **image_return; + XImage **shapeimage_return; + XpmImage *image; + XpmInfo *info; + XpmAttributes *attributes; +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + unsigned int depth; + int bitmap_format; + XpmFreeColorsFunc freeColors; + void *closure; + + /* variables to return */ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int mask_pixel_index = XpmUndefPixel; + + /* calculation variables */ + Pixel *image_pixels = NULL; + Pixel *mask_pixels = NULL; + Pixel *alloc_pixels = NULL; + Pixel *used_pixels = NULL; + unsigned int nalloc_pixels = 0; + unsigned int nused_pixels = 0; + unsigned int width, height, ncolors, cpp; + unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; + XpmColor *colorTable = NULL; + char *hints_cmt = NULL; + char *colors_cmt = NULL; + char *pixels_cmt = NULL; + + unsigned int cmts; + int ErrorStatus; + xpmHashTable hashtable; + + + /* 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)); + + if (attributes && (attributes->valuemask & XpmBitmapFormat)) + bitmap_format = attributes->bitmap_format; + else + bitmap_format = ZPixmap; + + if (attributes && (attributes->valuemask & XpmFreeColors)) + freeColors = attributes->free_colors; + else + freeColors = FreeColors; + if (attributes && (attributes->valuemask & XpmColorClosure)) + closure = attributes->color_closure; + else + closure = NULL; + + cmts = info && (info->valuemask & XpmReturnComments); + + /* + * parse the header + */ + ErrorStatus = xpmParseHeader(data); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * read values + */ + ErrorStatus = xpmParseValues(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 = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the colors comment line + */ + if (cmts) + xpmGetCmt(data, &colors_cmt); + + /* malloc pixels index tables */ + image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!image_pixels) + RETURN(XpmNoMemory); + + mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!mask_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!alloc_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!used_pixels) + RETURN(XpmNoMemory); + + /* get pixel colors, store them in index tables */ + ErrorStatus = CreateColors(display, attributes, colorTable, ncolors, + image_pixels, mask_pixels, &mask_pixel_index, + alloc_pixels, &nalloc_pixels, used_pixels, + &nused_pixels); + + if (ErrorStatus != XpmSuccess + && (ErrorStatus < 0 || (attributes + && (attributes->valuemask & XpmExactColors) + && attributes->exactColors))) + RETURN(ErrorStatus); + + /* now create the ximage */ + if (image_return) { + ErrorStatus = CreateXImage(display, visual, depth, + (depth == 1 ? bitmap_format : ZPixmap), + width, height, &ximage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#if !defined(FOR_MSW) && !defined(AMIGA) + + /* + * set the XImage pointer function, to be used with XPutPixel, + * to an internal optimized function + */ + + if (ximage->bits_per_pixel == 8) + ximage->f.put_pixel = PutPixel8; + else if (((ximage->bits_per_pixel | ximage->depth) == 1) && + (ximage->byte_order == ximage->bitmap_bit_order)) + if (ximage->bitmap_bit_order == MSBFirst) + ximage->f.put_pixel = PutPixel1MSB; + else + ximage->f.put_pixel = PutPixel1LSB; + else if (ximage->bits_per_pixel == 16) + if (ximage->bitmap_bit_order == MSBFirst) + ximage->f.put_pixel = PutPixel16MSB; + else + ximage->f.put_pixel = PutPixel16LSB; + else if (ximage->bits_per_pixel == 32) +#if !defined(WORD64) && !defined(LONG64) + if (*((char *)&byteorderpixel) == ximage->byte_order) + ximage->f.put_pixel = PutPixel32; + else +#endif + if (ximage->bitmap_bit_order == MSBFirst) + ximage->f.put_pixel = PutPixel32MSB; + else + ximage->f.put_pixel = PutPixel32LSB; + else if ((ximage->bits_per_pixel | ximage->depth) == 1) + ximage->f.put_pixel = PutPixel1; + else + ximage->f.put_pixel = PutPixel; +#endif /* not FOR_MSW && not AMIGA */ + } + + /* create the shape mask image */ + if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { + ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, + width, height, &shapeimage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#if !defined(FOR_MSW) && !defined(AMIGA) + if (shapeimage->bitmap_bit_order == MSBFirst) + shapeimage->f.put_pixel = PutPixel1MSB; + else + shapeimage->f.put_pixel = PutPixel1LSB; +#endif + } + + /* + * read pixels and put them in the XImage + */ + ErrorStatus = ParseAndPutPixels( +#ifdef FOR_MSW + display, +#endif + data, width, height, ncolors, cpp, + colorTable, &hashtable, + ximage, image_pixels, + shapeimage, mask_pixels); + XpmFree(image_pixels); + image_pixels = NULL; + XpmFree(mask_pixels); + mask_pixels = NULL; + + /* + * free the hastable + */ + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus) + else if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + + /* + * store the pixels comment line + */ + if (cmts) + xpmGetCmt(data, &pixels_cmt); + + /* + * parse extensions + */ + if (info && (info->valuemask & XpmReturnExtensions)) { + if (extensions) { + ErrorStatus = xpmParseExtensions(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 = NULL; + + 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; + } + } + /* if requested return used pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnPixels || +/* 3.2 backward compatibility code */ + attributes->valuemask & XpmReturnInfos)) { +/* end 3.2 bc */ + attributes->pixels = used_pixels; + attributes->npixels = nused_pixels; + attributes->mask_pixel = mask_pixel_index; + } else + XpmFree(used_pixels); + + /* if requested return alloc'ed pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { + attributes->alloc_pixels = alloc_pixels; + attributes->nalloc_pixels = nalloc_pixels; + } else + XpmFree(alloc_pixels); + + /* return created images */ + if (image_return) + *image_return = ximage; + if (shapeimage_return) + *shapeimage_return = shapeimage; + + return (XpmSuccess); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + if (colorTable) + xpmFreeColorTable(colorTable, ncolors); + if (hints_cmt) + XpmFree(hints_cmt); + if (colors_cmt) + XpmFree(colors_cmt); + if (pixels_cmt) + XpmFree(pixels_cmt); + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + if (image_pixels) + XpmFree(image_pixels); + if (mask_pixels) + XpmFree(mask_pixels); + if (nalloc_pixels) + (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); + if (alloc_pixels) + XpmFree(alloc_pixels); + if (used_pixels) + XpmFree(used_pixels); + + return (ErrorStatus); +} + +static int +ParseAndPutPixels( +#ifdef FOR_MSW + dc, +#endif + data, width, height, ncolors, cpp, colorTable, hashtable, + image, image_pixels, shapeimage, shape_pixels) +#ifdef FOR_MSW + Display *dc; +#endif + xpmData *data; + unsigned int width; + unsigned int height; + unsigned int ncolors; + unsigned int cpp; + XpmColor *colorTable; + xpmHashTable *hashtable; + XImage *image; + Pixel *image_pixels; + XImage *shapeimage; + Pixel *shape_pixels; +{ + unsigned int a, x, y; + + switch (cpp) { + + case (1): /* Optimize for single character + * colors */ + { + unsigned short colidx[256]; +#ifdef FOR_MSW + HDC shapedc; + HBITMAP obm, sobm; + + if ( shapeimage ) { + shapedc = CreateCompatibleDC(*dc); + sobm = SelectObject(shapedc, shapeimage->bitmap); + } else { + shapedc = NULL; + } + obm = SelectObject(*dc, image->bitmap); +#endif + + + bzero((char *)colidx, 256 * sizeof(short)); + for (a = 0; a < ncolors; a++) + colidx[(unsigned char)colorTable[a].string[0]] = a + 1; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + int c = xpmGetC(data); + + if (c > 0 && c < 256 && colidx[c] != 0) { +#ifndef FOR_MSW + XPutPixel(image, x, y, image_pixels[colidx[c] - 1]); + if (shapeimage) + XPutPixel(shapeimage, x, y, + shape_pixels[colidx[c] - 1]); +#else + SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]); + if (shapedc) { + SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]); + } +#endif + } else + return (XpmFileInvalid); + } + } +#ifdef FOR_MSW + if ( shapedc ) { + SelectObject(shapedc, sobm); + DeleteDC(shapedc); + } + SelectObject(*dc, obm); +#endif + } + 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; + return (XpmNoMemory); + } + } + cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1; + } + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + int cc1 = xpmGetC(data); + if (cc1 > 0 && cc1 < 256) { + int cc2 = xpmGetC(data); + if (cc2 > 0 && cc2 < 256 && + cidx[cc1] && cidx[cc1][cc2] != 0) { +#ifndef FOR_MSW + XPutPixel(image, x, y, + image_pixels[cidx[cc1][cc2] - 1]); + if (shapeimage) + XPutPixel(shapeimage, x, y, + shape_pixels[cidx[cc1][cc2] - 1]); +#else + SelectObject(*dc, image->bitmap); + SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]); + if (shapeimage) { + SelectObject(*dc, shapeimage->bitmap); + SetPixel(*dc, x, y, + shape_pixels[cidx[cc1][cc2] - 1]); + } +#endif + } else { + FREE_CIDX; + return (XpmFileInvalid); + } + } else { + FREE_CIDX; + 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++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + slot = xpmHashSlot(hashtable, buf); + if (!*slot) /* no color matches */ + return (XpmFileInvalid); +#ifndef FOR_MSW + XPutPixel(image, x, y, + image_pixels[HashColorIndex(slot)]); + if (shapeimage) + XPutPixel(shapeimage, x, y, + shape_pixels[HashColorIndex(slot)]); +#else + SelectObject(*dc, image->bitmap); + SetPixel(*dc, x, y, + image_pixels[HashColorIndex(slot)]); + if (shapeimage) { + SelectObject(*dc, shapeimage->bitmap); + SetPixel(*dc, x, y, + shape_pixels[HashColorIndex(slot)]); + } +#endif + } + } + } else { + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + 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 */ + return (XpmFileInvalid); +#ifndef FOR_MSW + XPutPixel(image, x, y, image_pixels[a]); + if (shapeimage) + XPutPixel(shapeimage, x, y, shape_pixels[a]); +#else + SelectObject(*dc, image->bitmap); + SetPixel(*dc, x, y, image_pixels[a]); + if (shapeimage) { + SelectObject(*dc, shapeimage->bitmap); + SetPixel(*dc, x, y, shape_pixels[a]); + } +#endif + } + } + } + } + break; + } + return (XpmSuccess); +} diff --git a/src/data.c b/src/data.c new file mode 100644 index 0000000..dea87b4 --- /dev/null +++ b/src/data.c @@ -0,0 +1,476 @@ +/* + * Copyright (C) 1989-95 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 * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/data.c,v 1.4 2002/01/07 19:40:49 dawes Exp $ */ + +#ifndef CXPMPROG +#if 0 +/* Official version number */ +static char *RCS_Version = "$XpmVersion: 3.4k $"; + +/* Internal version number */ +static char *RCS_Id = "Id: xpm.shar,v 3.71 1998/03/19 19:47:14 lehors Exp $"; +#endif +#include "XpmI.h" +#endif +#include + +#ifndef CXPMPROG +#define Getc(data, file) getc(file) +#define Ungetc(data, c, file) ungetc(c, file) +#endif + +static int +ParseComment(xpmData *data) +{ + if (data->type == XPMBUFFER) { + register char c; + register unsigned int n = 0; + unsigned int notend; + char *s, *s2; + + s = data->Comment; + *s = data->Bcmt[0]; + + /* skip the string beginning comment */ + s2 = data->Bcmt; + do { + c = *data->cptr++; + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c); + + if (*s2 != '\0') { + /* this wasn't the beginning of a comment */ + data->cptr -= n; + return 0; + } + /* store comment */ + data->Comment[0] = *s; + s = data->Comment; + notend = 1; + n = 0; + while (notend) { + s2 = data->Ecmt; + while (*s != *s2 && c) { + c = *data->cptr++; + if (n == XPMMAXCMTLEN - 1) { /* forget it */ + s = data->Comment; + n = 0; + } + *++s = c; + n++; + } + data->CommentLength = n; + do { + c = *data->cptr++; + if (n == XPMMAXCMTLEN - 1) { /* forget it */ + s = data->Comment; + n = 0; + } + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c); + if (*s2 == '\0') { + /* this is the end of the comment */ + notend = 0; + data->cptr--; + } + } + return 0; + } else { + FILE *file = data->stream.file; + register int c; + register unsigned int n = 0, a; + unsigned int notend; + char *s, *s2; + + s = data->Comment; + *s = data->Bcmt[0]; + + /* skip the string beginning comment */ + s2 = data->Bcmt; + do { + c = Getc(data, file); + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c != EOF); + + 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(data, *s, file); + return 0; + } + /* store comment */ + data->Comment[0] = *s; + s = data->Comment; + notend = 1; + n = 0; + while (notend) { + s2 = data->Ecmt; + while (*s != *s2 && c != EOF) { + c = Getc(data, file); + if (n == XPMMAXCMTLEN - 1) { /* forget it */ + s = data->Comment; + n = 0; + } + *++s = c; + n++; + } + data->CommentLength = n; + do { + c = Getc(data, file); + if (n == XPMMAXCMTLEN - 1) { /* forget it */ + s = data->Comment; + n = 0; + } + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c != EOF); + if (*s2 == '\0') { + /* this is the end of the comment */ + notend = 0; + Ungetc(data, *s, file); + } + } + return 0; + } +} + +/* + * skip to the end of the current string and the beginning of the next one + */ +int +xpmNextString(data) + xpmData *data; +{ + if (!data->type) + data->cptr = (data->stream.data)[++data->line]; + else if (data->type == XPMBUFFER) { + register char c; + + /* get to the end of the current string */ + if (data->Eos) + while ((c = *data->cptr++) && c != data->Eos); + + /* + * then get to the beginning of the next string looking for possible + * comment + */ + if (data->Bos) { + while ((c = *data->cptr++) && c != data->Bos) + if (data->Bcmt && c == data->Bcmt[0]) + ParseComment(data); + } else if (data->Bcmt) { /* XPM2 natural */ + while ((c = *data->cptr++) == data->Bcmt[0]) + ParseComment(data); + data->cptr--; + } + } else { + register int c; + FILE *file = data->stream.file; + + /* get to the end of the current string */ + if (data->Eos) + while ((c = Getc(data, file)) != data->Eos && c != EOF); + + /* + * then get to the beginning of the next string looking for possible + * comment + */ + if (data->Bos) { + while ((c = Getc(data, file)) != data->Bos && c != EOF) + if (data->Bcmt && c == data->Bcmt[0]) + ParseComment(data); + + } else if (data->Bcmt) { /* XPM2 natural */ + while ((c = Getc(data, file)) == data->Bcmt[0]) + ParseComment(data); + Ungetc(data, c, file); + } + } + return 0; +} + + +/* + * skip whitespace and return the following word + */ +unsigned int +xpmNextWord(data, buf, buflen) + xpmData *data; + char *buf; + unsigned int buflen; +{ + register unsigned int n = 0; + int c; + + if (!data->type || data->type == XPMBUFFER) { + while (isspace(c = *data->cptr) && c != data->Eos) + data->cptr++; + do { + c = *data->cptr++; + *buf++ = c; + n++; + } while (!isspace(c) && c != data->Eos && n < buflen); + n--; + data->cptr--; + } else { + FILE *file = data->stream.file; + + while ((c = Getc(data, file)) != EOF && isspace(c) && c != data->Eos); + while (!isspace(c) && c != data->Eos && c != EOF && n < buflen) { + *buf++ = c; + n++; + c = Getc(data, file); + } + Ungetc(data, c, file); + } + return (n); +} + +/* + * skip whitespace and compute the following unsigned int, + * returns 1 if one is found and 0 if not + */ +int +xpmNextUI(data, ui_return) + xpmData *data; + unsigned int *ui_return; +{ + char buf[BUFSIZ]; + int l; + + l = xpmNextWord(data, buf, BUFSIZ); + return xpmatoui(buf, l, ui_return); +} + +/* + * return end of string - WARNING: malloc! + */ +int +xpmGetString(data, sptr, l) + xpmData *data; + char **sptr; + unsigned int *l; +{ + unsigned int i, n = 0; + int c; + char *p = NULL, *q, buf[BUFSIZ]; + + if (!data->type || data->type == XPMBUFFER) { + if (data->cptr) { + char *start = data->cptr; + while ((c = *data->cptr) && c != data->Eos) + data->cptr++; + n = data->cptr - start + 1; + p = (char *) XpmMalloc(n); + if (!p) + return (XpmNoMemory); + strncpy(p, start, n); + if (data->type) /* XPMBUFFER */ + p[n - 1] = '\0'; + } + } else { + FILE *file = data->stream.file; + + if ((c = Getc(data, file)) == EOF) + return (XpmFileInvalid); + + i = 0; + q = buf; + p = (char *) XpmMalloc(1); + while (c != data->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(data, 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(data, c, file); + } + *sptr = p; + *l = n; + return (XpmSuccess); +} + +/* + * get the current comment line + */ +int +xpmGetCmt(data, cmt) + xpmData *data; + char **cmt; +{ + if (!data->type) + *cmt = NULL; + else if (data->CommentLength) { + *cmt = (char *) XpmMalloc(data->CommentLength + 1); + strncpy(*cmt, data->Comment, data->CommentLength); + (*cmt)[data->CommentLength] = '\0'; + data->CommentLength = 0; + } else + *cmt = NULL; + return 0; +} + +xpmDataType xpmDataTypes[] = +{ + {"", "!", "\n", '\0', '\n', "", "", "", ""}, /* Natural type */ + {"C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n"}, + {"Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n"}, + {NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL} +}; + +/* + * parse xpm header + */ +int +xpmParseHeader(data) + xpmData *data; +{ + char buf[BUFSIZ]; + int l, n = 0; + + if (data->type) { + data->Bos = '\0'; + data->Eos = '\n'; + data->Bcmt = data->Ecmt = NULL; + l = xpmNextWord(data, buf, BUFSIZ); + if (l == 7 && !strncmp("#define", buf, 7)) { + /* this maybe an XPM 1 file */ + char *ptr; + + l = xpmNextWord(data, buf, BUFSIZ); + if (!l) + return (XpmFileInvalid); + buf[l] = '\0'; + ptr = rindex(buf, '_'); + if (!ptr || strncmp("_format", ptr, l - (ptr - buf))) + return XpmFileInvalid; + /* this is definitely an XPM 1 file */ + data->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(data, 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(data, buf, BUFSIZ); + + /* + * get infos about this type + */ + while (xpmDataTypes[n].type + && strncmp(xpmDataTypes[n].type, buf, l)) + n++; + } + data->format = 0; + } else + /* nope this is not an XPM file */ + return XpmFileInvalid; + } + if (xpmDataTypes[n].type) { + if (n == 0) { /* natural type */ + data->Bcmt = xpmDataTypes[n].Bcmt; + data->Ecmt = xpmDataTypes[n].Ecmt; + xpmNextString(data); /* skip the end of the headerline */ + data->Bos = xpmDataTypes[n].Bos; + data->Eos = xpmDataTypes[n].Eos; + } else { + data->Bcmt = xpmDataTypes[n].Bcmt; + data->Ecmt = xpmDataTypes[n].Ecmt; + if (!data->format) { /* XPM 2 or 3 */ + data->Bos = xpmDataTypes[n].Bos; + data->Eos = '\0'; + /* get to the beginning of the first string */ + xpmNextString(data); + data->Eos = xpmDataTypes[n].Eos; + } else /* XPM 1 skip end of line */ + xpmNextString(data); + } + } else + /* we don't know about that type of XPM file... */ + return XpmFileInvalid; + } + return XpmSuccess; +} diff --git a/src/hashtab.c b/src/hashtab.c new file mode 100644 index 0000000..7d596ec --- /dev/null +++ b/src/hashtab.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 1989-95 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. + */ + +/*****************************************************************************\ +* hashtab.c: * +* * +* XPM library * +* * +* Developed by Arnaud Le Hors * +* this originaly comes from Colas Nahaboo as a part of Wool * +* * +\*****************************************************************************/ + +#include "XpmI.h" + +LFUNC(AtomMake, xpmHashAtom, (char *name, void *data)); +LFUNC(HashTableGrows, int, (xpmHashTable * table)); + +static xpmHashAtom +AtomMake(name, 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(table, s) + 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(table) + 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(table, tag, data) + 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(table) + 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(table) + xpmHashTable *table; +{ + xpmHashAtom *p; + xpmHashAtom *atomTable = table->atomTable; + + if (!atomTable) + return; + for (p = atomTable + table->size; p > atomTable;) + if (*--p) + XpmFree(*p); + XpmFree(atomTable); + table->atomTable = NULL; +} diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..7a9ecb5 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 1989-95 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 * +\*****************************************************************************/ + +#include "XpmI.h" + +#ifdef NEED_STRDUP +/* + * in case strdup is not provided by the system here is one + * which does the trick + */ +char * +xpmstrdup(s1) + char *s1; +{ + char *s2; + int l = strlen(s1) + 1; + + if (s2 = (char *) XpmMalloc(l)) + strcpy(s2, s1); + return s2; +} + +#endif + +unsigned int +xpmatoui(p, l, ui_return) + 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; +} + +/* + * Function returning a character string related to an error code. + */ +char * +XpmGetErrorString(errcode) + 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; +} + + +/* The following should help people wanting to use their own functions */ +#ifdef XpmFree +#undef XpmFree +#endif + +void +XpmFree(ptr) + void *ptr; +{ + free(ptr); +} diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..fc8cd2b --- /dev/null +++ b/src/parse.c @@ -0,0 +1,749 @@ +/* + * Copyright (C) 1989-95 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. + */ +/* $XFree86: xc/extras/Xpm/lib/parse.c,v 1.3 2001/10/28 03:32:10 tsi Exp $ */ + +/*****************************************************************************\ +* 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 * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/parse.c,v 1.3 2001/10/28 03:32:10 tsi Exp $ */ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#include "XpmI.h" +#include +#include + +LFUNC(ParsePixels, int, (xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, unsigned int **pixels)); + +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 */ +}; + +int +xpmParseValues(data, width, height, ncolors, cpp, + x_hotspot, y_hotspot, hotspot, extensions) + xpmData *data; + unsigned int *width, *height, *ncolors, *cpp; + unsigned int *x_hotspot, *y_hotspot, *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 = (xpmatoui(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; + Bool got_one, saw_width = False, saw_height = False; + Bool saw_ncolors = False, saw_chars_per_pixel = False; + + 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); + buf[l] = '\0'; + ptr = buf; + got_one = False; + while (!got_one) { + ptr = index(ptr, '_'); + if (!ptr) + return (XpmFileInvalid); + switch (l - (ptr - buf)) { + case 6: + if (saw_width || strncmp("_width", ptr, 6) + || !xpmNextUI(data, width)) + return (XpmFileInvalid); + else + saw_width = True; + got_one = True; + break; + case 7: + if (saw_height || strncmp("_height", ptr, 7) + || !xpmNextUI(data, height)) + return (XpmFileInvalid); + else + saw_height = True; + got_one = True; + break; + case 8: + if (saw_ncolors || strncmp("_ncolors", ptr, 8) + || !xpmNextUI(data, ncolors)) + return (XpmFileInvalid); + else + saw_ncolors = True; + got_one = True; + break; + case 16: + if (saw_chars_per_pixel + || strncmp("_chars_per_pixel", ptr, 16) + || !xpmNextUI(data, cpp)) + return (XpmFileInvalid); + else + saw_chars_per_pixel = True; + got_one = True; + break; + default: + ptr++; + } + } + /* skip the end of line */ + xpmNextString(data); + } + if (!saw_width || !saw_height || !saw_ncolors || !saw_chars_per_pixel) + return (XpmFileInvalid); + + *hotspot = 0; + *extensions = 0; + } + return (XpmSuccess); +} + +int +xpmParseColors(data, ncolors, cpp, colorTablePtr, hashtable) + xpmData *data; + unsigned int ncolors; + unsigned int cpp; + XpmColor **colorTablePtr; + xpmHashTable *hashtable; +{ + unsigned int key = 0, 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(data, width, height, ncolors, cpp, colorTable, hashtable, pixels) + 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[(unsigned char)colorTable[a].string[0]] = a + 1; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + int c = xpmGetC(data); + + if (c > 0 && c < 256 && colidx[c] != 0) + *iptr = colidx[c] - 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][(unsigned char)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); + if (cc1 > 0 && cc1 < 256) { + int cc2 = xpmGetC(data); + if (cc2 > 0 && cc2 < 256 && + cidx[cc1] && cidx[cc1][cc2] != 0) + *iptr = cidx[cc1][cc2] - 1; + else { + FREE_CIDX; + XpmFree(iptr2); + return (XpmFileInvalid); + } + } 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); +} + +int +xpmParseExtensions(data, extensions, nextensions) + 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); +} + + +/* function call in case of error */ +#undef RETURN +#define RETURN(status) \ +{ \ + goto error; \ +} + +/* + * This function parses an Xpm file or data and store the found informations + * in an an XpmImage structure which is returned. + */ +int +xpmParseData(data, image, info) + 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 = xpmParseValues(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 = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); + if (ErrorStatus != XpmSuccess) { + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + 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 = xpmParseExtensions(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); + +/* exit point in case of error, free only locally allocated variables */ +error: + 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(ErrorStatus); +} diff --git a/src/rgb.c b/src/rgb.c new file mode 100644 index 0000000..b26ee3f --- /dev/null +++ b/src/rgb.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 1989-95 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 "XpmI.h" +#include + +#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(rgb_fname, rgbn) + char *rgb_fname; + xpmRgbName rgbn[]; + +{ + FILE *rgbf; + int n, items, red, green, blue; + char line[512], name[512], *rgbname, *s1, *s2; + 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. */ + n = 0; + rgb = rgbn; + /* Quit if rgb text file has too many entries. */ + while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) { + + /* Skip silently if line is bad. */ + items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); + if (items != 4) + 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) + 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 (s1 = name, s2 = rgbname; *s1; s1++) + *s2++ = tolower(*s1); + *s2 = '\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; + rgb++; + n++; + } + + fclose(rgbf); + + /* Return the number of read rgb names. */ + return n < 0 ? 0 : n; +} + +/* + * Return the color name corresponding to the given rgb values + */ +char * +xpmGetRgbName(rgbn, rgbn_max, red, green, 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(rgbn, rgbn_max) + 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(rgb_fname, rgbn) + 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(rgbn, rgbn_max, red, green, 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(inname, r, g, b) + char *inname; + int *r, *g, *b; +{ + int left, right, middle; + int cmp; + unsigned long rgbVal; + char *name; + char *grey, *p; + + name = xpmstrdup(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 = xpmstrcasecmp(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(rgbn, rgbn_max) + xpmRgbName rgbn[]; + int rgbn_max; + +{ + /* nothing to do */ +} + +#endif /* MSW part */ diff --git a/src/rgbtab.h b/src/rgbtab.h new file mode 100644 index 0000000..3b75184 --- /dev/null +++ b/src/rgbtab.h @@ -0,0 +1,292 @@ +/* + * Copyright (C) 1989-95 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/scan.c b/src/scan.c new file mode 100644 index 0000000..6175ca4 --- /dev/null +++ b/src/scan.c @@ -0,0 +1,1007 @@ +/* + * Copyright (C) 1989-95 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 * +\*****************************************************************************/ +/* $XFree86: xc/extras/Xpm/lib/scan.c,v 1.3 2002/01/07 19:40:49 dawes Exp $ */ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +#include "XpmI.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)); + +typedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap, + unsigned int *index_return); + +#ifndef FOR_MSW +# ifndef AMIGA +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, + storeFuncPtr storeFunc)); +# else /* AMIGA */ +LFUNC(AGetImagePixels, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap, + storeFuncPtr storeFunc)); +# endif/* AMIGA */ +#else /* ndef FOR_MSW */ +LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap, + storeFuncPtr storeFunc)); +#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, pmap, index_return) + 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, pmap, index_return) + 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 */ +#undef RETURN +#define RETURN(status) \ +{ \ + ErrorStatus = status; \ + goto error; \ +} + +/* + * This function scans the given image and stores the found informations in + * the given XpmImage structure. + */ +int +XpmCreateXpmImageFromImage(display, image, shapeimage, + xpmimage, attributes) + 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 = 0; + + /* calculation variables */ + unsigned int width = 0; + unsigned int height = 0; + unsigned int cppm; /* minimum chars per pixel */ + unsigned int c; + + /* 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 +# ifndef AMIGA + ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap, + storeMaskPixel); +# else + ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap, + storeMaskPixel); +# endif +#else + ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height, + &pmap, storeMaskPixel); +#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 +# ifndef AMIGA + if (((image->bits_per_pixel | image->depth) == 1) && + (image->byte_order == image->bitmap_bit_order)) + ErrorStatus = GetImagePixels1(image, width, height, &pmap, + storePixel); + else if (image->format == ZPixmap) { + 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 + ErrorStatus = AGetImagePixels(image, width, height, &pmap, + storePixel); +# endif +#else + ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap, + storePixel); +#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); + } + + ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors, + pmap.pixels, 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); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (pmap.pixelindex) + XpmFree(pmap.pixelindex); + if (pmap.pixels) + XpmFree(pmap.pixels); + if (colorTable) + xpmFreeColorTable(colorTable, pmap.ncolors); + + return (ErrorStatus); +} + +static int +ScanTransparentColor(color, cpp, attributes) + 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->valuemask & XpmColorTable +/* 3.2 backward compatibility code */ + || attributes->valuemask & XpmInfos) +/* end 3.2 bc */ + && attributes->mask_pixel != XpmUndefPixel) { + + unsigned int key; + char **defaults = (char **) color; + char **mask_defaults; + +/* 3.2 backward compatibility code */ + if (attributes->valuemask & XpmColorTable) +/* end 3.2 bc */ + mask_defaults = (char **) ( + attributes->colorTable + attributes->mask_pixel); +/* 3.2 backward compatibility code */ + else + mask_defaults = (char **) + ((XpmColor **) attributes->colorTable)[attributes->mask_pixel]; +/* end 3.2 bc */ + for (key = 1; key <= NKEYS; key++) { + if ((s = mask_defaults[key])) { + defaults[key] = (char *) xpmstrdup(s); + if (!defaults[key]) + return (XpmNoMemory); + } + } + } else { + color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR); + if (!color->c_color) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +static int +ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes) + 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 = NULL, **oldColorTable = NULL; + unsigned int ancolors = 0; + Pixel *apixels = NULL; + unsigned int mask_pixel = 0; + Bool 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; + + /* start from the right element */ + if (mask) { + colors++; + ncolors--; + pixels++; + } + + /* first get character strings and rgb values */ + xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors); + if (!xcolors) + return (XpmNoMemory); + + for (i = 0, i2 = mask, 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; + } + XQueryColors(display, colormap, xcolors, ncolors); + +#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 *) xpmstrdup(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 *) xpmstrdup(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 *) xpmstrdup(buf); + } + if (!color->c_color) { + XpmFree(xcolors); + xpmFreeRgbNames(rgbn, rgbn_max); + return (XpmNoMemory); + } + } + } + + XpmFree(xcolors); + xpmFreeRgbNames(rgbn, rgbn_max); + return (XpmSuccess); +} + +#ifndef FOR_MSW +# ifndef AMIGA +/* + * 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. + */ + +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 an 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(image, width, height, pmap) + 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, offset; + 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; + offset = image->xoffset; + + if ((image->bits_per_pixel | 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 + offset) % ibu; + pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1; + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else if (image->format == XYPixmap) { + int nbytes, bpl, j; + long plane = 0; + ibu = image->bitmap_unit; + nbytes = ibu >> 3; + bpl = image->bytes_per_line; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = 0; + plane = 0; + for (i = depth; --i >= 0;) { + src = &data[XYINDEX(x, y, image) + plane]; + dst = (char *) &px; + px = 0; + for (j = nbytes; --j >= 0;) + *dst++ = *src++; + XYNORMALIZE(&px, image); + bits = (x + offset) % ibu; + pixel = (pixel << 1) | + (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1); + plane = plane + (bpl * height); + } + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else if (image->format == ZPixmap) { + 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); + } + } else + return (XpmColorError); /* actually a bad image */ + return (XpmSuccess); +} + +/* + * scan pixels of a 32-bits Z image data structure + */ + +#if !defined(WORD64) && !defined(LONG64) +static unsigned long byteorderpixel = MSBFirst << 24; +#endif + +static int +GetImagePixels32(image, width, height, pmap) + 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 !defined(WORD64) && !defined(LONG64) + 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[3]); + 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(image, width, height, pmap) + 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(image, width, height, pmap) + 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(image, width, height, pmap, storeFunc) + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; + storeFuncPtr storeFunc; +{ + unsigned int *iptr; + int x, y; + char *data; + Pixel pixel; + int xoff, yoff, offset, bpl; + + data = image->data; + iptr = pmap->pixelindex; + offset = image->xoffset; + bpl = image->bytes_per_line; + + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + xoff = x + offset; + yoff = y * bpl + (xoff >> 3); + xoff &= 7; + pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + xoff = x + offset; + yoff = y * bpl + (xoff >> 3); + xoff &= 7; + pixel = (data[yoff] & (1 << xoff)) ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +# else /* AMIGA */ + +#define CLEAN_UP(status) \ +{\ + if (pixels) XpmFree (pixels);\ + if (tmp_img) FreeXImage (tmp_img);\ + return (status);\ +} + +static int +AGetImagePixels ( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap, + int (*storeFunc) ()) +{ + unsigned int *iptr; + unsigned int x, y; + unsigned char *pixels; + XImage *tmp_img; + + pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels)); + if (pixels == NULL) + return XpmNoMemory; + + tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth); + if (tmp_img == NULL) + CLEAN_UP (XpmNoMemory) + + iptr = pmap->pixelindex; + for (y = 0; y < height; ++y) + { + ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp); + for (x = 0; x < width; ++x, ++iptr) + { + if ((*storeFunc) (pixels[x], pmap, iptr)) + CLEAN_UP (XpmNoMemory) + } + } + + CLEAN_UP (XpmSuccess) +} + +#undef CLEAN_UP + +# endif/* AMIGA */ +#else /* ndef FOR_MSW */ +static int +MSWGetImagePixels(display, image, width, height, pmap, storeFunc) + Display *display; + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; + int (*storeFunc) (); +{ + unsigned int *iptr; + unsigned int x, y; + Pixel pixel; + + iptr = pmap->pixelindex; + + SelectObject(*display, image->bitmap); + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++, iptr++) { + pixel = GetPixel(*display, x, y); + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return (XpmSuccess); +} + +#endif + +#ifndef FOR_MSW +# ifndef AMIGA +int +XpmCreateXpmImageFromPixmap(display, pixmap, shapemask, + xpmimage, attributes) + 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/* not AMIGA */ +#endif /* ndef FOR_MSW */ diff --git a/src/simx.c b/src/simx.c new file mode 100644 index 0000000..5e5537d --- /dev/null +++ b/src/simx.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) 1989-95 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) * +\*****************************************************************************/ + +#ifdef FOR_MSW + +#include "xpm.h" +#include "xpmi.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(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) { + /*JW: This is what it should be, but the picture comes out + just black!? It appears to be doing monochrome reduction, + but I've got no clue why. Using CreateBitmap() is supposed + to be slower, but otherwise ok + if ( depth == GetDeviceCaps(*d, BITSPIXEL) ) { + img->bitmap = CreateCompatibleBitmap(*d, width, height); + } else*/ { + 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/simx.h b/src/simx.h new file mode 100644 index 0000000..001cfdb --- /dev/null +++ b/src/simx.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 1989-95 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 */ +#define XYBitmap 1 /* not really used */ + +#ifndef True +#define True 1 +#define False 0 +#endif +#ifndef Bool +typedef BOOL Bool; /* take MSW 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/sxpm/plaid.xpm b/sxpm/plaid.xpm new file mode 100644 index 0000000..b0e9200 --- /dev/null +++ b/sxpm/plaid.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 4 2 ", +/* colors */ +" c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +/* pixels */ +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x " +} ; diff --git a/sxpm/plaid_ext.xpm b/sxpm/plaid_ext.xpm new file mode 100644 index 0000000..8538952 --- /dev/null +++ b/sxpm/plaid_ext.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 4 2 XPMEXT", +/* colors */ +" c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +/* pixels */ +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"XPMEXT ext1 data1", +"XPMEXT ext2", +"data2_1", +"data2_2", +"XPMEXT ext3", +"data3", +"XPMEXT", +"data4", +"XPMENDEXT" +} ; diff --git a/sxpm/plaid_mask.xpm b/sxpm/plaid_mask.xpm new file mode 100644 index 0000000..167d338 --- /dev/null +++ b/sxpm/plaid_mask.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 5 2", +/* colors */ +". c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +" c none s mask ", +/* pixels */ +" x x x x x + x x x x x ", +" . x x x x x x x x x x x ", +" . x x x x x x + x x x x x ", +" . x . x x x x x x x x x x x ", +" . x . x x x x x x + x x x x x ", +" Y Y Y Y Y + x + x + x + x + x + ", +" x x . x . x x x x x x + x x x x x ", +" . x . x . x . x x x x x x x x x x x ", +" . x x x . x . x x x x x x + x x x x x ", +" . x . x . x . x . x x x x x x x x x x x ", +" . x . x x x . x . x x x x x x + x x x x x ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x " +} ; diff --git a/sxpm/sxpm.c b/sxpm/sxpm.c new file mode 100644 index 0000000..b98ea9f --- /dev/null +++ b/sxpm/sxpm.c @@ -0,0 +1,709 @@ +/* + * Copyright (C) 1989-95 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. + */ +/* $XFree86: xc/extras/Xpm/sxpm/sxpm.c,v 1.3 2001/10/28 03:32:13 tsi Exp $ */ + +/*****************************************************************************\ +* sxpm.c: * +* * +* Show XPM File program * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#ifdef VMS +#include +#else +#include +#endif + +#include + +/* XPM */ +/* plaid pixmap */ +static char *plaid[] = { + /* width height ncolors chars_per_pixel */ + "22 22 4 2 XPMEXT", + /* colors */ + " c red m white s light_color", + "Y c green m black s lines_in_mix", + "+ c yellow m white s lines_in_dark", + "x m black s dark_color", + /* pixels */ + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + "Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + "x x x x x x x x x x x x x x x x x x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + "bullshit", + "XPMEXT ext1 data1", + "XPMEXT ext2", + "data2_1", + "data2_2", + "XPMEXT", + "foo", + "", + "XPMEXT ext3", + "data3", + "XPMENDEXT" +}; + +#define win XtWindow(topw) +#define dpy XtDisplay(topw) +#define root XRootWindowOfScreen(XtScreen(topw)) +#define xrdb XtDatabase(dpy) +static Colormap colormap; + +void Usage(); +void ErrorMessage(); +void Punt(); +void VersionInfo(); + +#ifdef __STDC__ +void kinput(Widget widget, char *tag, XEvent *xe, Boolean *b); +#else +void kinput(); +#endif + +#define IWIDTH 50 +#define IHEIGHT 50 + +typedef struct _XpmIcon { + Pixmap pixmap; + Pixmap mask; + XpmAttributes attributes; +} XpmIcon; + +static char **command; +static Widget topw; +static XpmIcon view, icon; +static XrmOptionDescRec options[] = { + {"-hints", ".hints", XrmoptionNoArg, (XtPointer) "True"}, + {"-icon", ".icon", XrmoptionSepArg, (XtPointer) NULL}, +}; + +int +main(argc, argv) + int argc; + char **argv; +{ + int ErrorStatus; + unsigned int verbose = 0; /* performs verbose output */ + unsigned int stdinf = 1; /* read from stdin */ + unsigned int stdoutf = 0; /* write to stdout */ + unsigned int nod = 0; /* no display */ + unsigned int nom = 0; /* no mask display */ + unsigned int incResize = 0; + unsigned int resize = 0; + unsigned int w_rtn; + unsigned int h_rtn; + char *input = NULL; + char *output = NULL; + char *iconFile = NULL; + unsigned int numsymbols = 0; + XpmColorSymbol symbols[10]; + char *stype; + XrmValue val; + unsigned long valuemask = 0; + int n; + Arg args[4]; + +#ifdef Debug + char **data; + char *buffer; +#endif + + topw = XtInitialize(argv[0], "Sxpm", + options, XtNumber(options), &argc, argv); + + if (!topw) { + fprintf(stderr, "Sxpm Error... [ Undefined DISPLAY ]\n"); + exit(1); + } + colormap = XDefaultColormapOfScreen(XtScreen(topw)); + + /* + * geometry management + */ + + if (XrmGetResource(xrdb, NULL, "sxpm.geometry", &stype, &val) + || XrmGetResource(xrdb, NULL, "Sxpm.geometry", &stype, &val)) { + + int flags; + int x_rtn; + int y_rtn; + char *geo = NULL; + + geo = (char *) val.addr; + flags = XParseGeometry(geo, &x_rtn, &y_rtn, + (unsigned int *) &w_rtn, + (unsigned int *) &h_rtn); + + if (!((WidthValue & flags) && (HeightValue & flags))) + resize = 1; + + } else + resize = 1; + + n = 0; + if (resize) { + w_rtn = 0; + h_rtn = 0; + XtSetArg(args[n], XtNwidth, 1); + n++; + XtSetArg(args[n], XtNheight, 1); + n++; + } + XtSetArg(args[n], XtNmappedWhenManaged, False); + n++; + XtSetArg(args[n], XtNinput, True); + n++; + XtSetValues(topw, args, n); + + if ((XrmGetResource(xrdb, "sxpm.hints", "", &stype, &val) + || XrmGetResource(xrdb, "Sxpm.hints", "", &stype, &val)) + && !strcmp((char *) val.addr, "True")) { + /* gotcha */ + incResize = 1; + resize = 1; + } + + /* + * icon management + */ + + if (XrmGetResource(xrdb, "sxpm.icon", "", &stype, &val) + || XrmGetResource(xrdb, "Sxpm.icon", "", &stype, &val)) { + iconFile = (char *) val.addr; + } + if (iconFile) { + + XColor color, junk; + Pixel bpix; + Window iconW; + + if (XAllocNamedColor(dpy, colormap, "black", &color, &junk)) + bpix = color.pixel; + else + bpix = XBlackPixelOfScreen(XtScreen(topw)); + + iconW = XCreateSimpleWindow(dpy, root, 0, 0, + IWIDTH, IHEIGHT, 1, bpix, bpix); + + icon.attributes.valuemask = XpmReturnAllocPixels; + ErrorStatus = XpmReadFileToPixmap(dpy, root, iconFile, &icon.pixmap, + &icon.mask, &icon.attributes); + ErrorMessage(ErrorStatus, "Icon"); + + XSetWindowBackgroundPixmap(dpy, iconW, icon.pixmap); + + n = 0; + XtSetArg(args[n], XtNbackground, bpix); + n++; + XtSetArg(args[n], XtNiconWindow, iconW); + n++; + XtSetValues(topw, args, n); + } + + /* + * arguments parsing + */ + + command = argv; + for (n = 1; n < argc; n++) { + if (strcmp(argv[n], "-plaid") == 0) { + stdinf = 0; + continue; + } + if (argv[n][0] != '-') { + stdinf = 0; + input = argv[n]; + continue; + } + if ((strlen(argv[n]) == 1) && (argv[n][0] == '-')) + /* stdin */ + continue; + if (strcmp(argv[n], "-o") == 0) { + if (n < argc - 1) { + if ((strlen(argv[n + 1]) == 1) && (argv[n + 1][0] == '-')) + stdoutf = 1; + else + output = argv[n + 1]; + n++; + continue; + } else + Usage(); + } + if (strcmp(argv[n], "-nod") == 0) { + nod = 1; + continue; + } + if (strcmp(argv[n], "-nom") == 0) { + nom = 1; + continue; + } + if (strcmp(argv[n], "-sc") == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols++].value = argv[++n]; + continue; + } else + Usage(); + } + if (strcmp(argv[n], "-sp") == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols].value = NULL; + symbols[numsymbols++].pixel = atol(argv[++n]); + continue; + } + } + if (strcmp(argv[n], "-cp") == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = NULL; + symbols[numsymbols].value = argv[++n]; + symbols[numsymbols++].pixel = atol(argv[++n]); + continue; + } + } + if (strcmp(argv[n], "-mono") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_MONO; + continue; + } + if (strcmp(argv[n], "-gray4") == 0 || strcmp(argv[n], "-grey4") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_GRAY4; + continue; + } + if (strcmp(argv[n], "-gray") == 0 || strcmp(argv[n], "-grey") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_GRAY; + continue; + } + if (strcmp(argv[n], "-color") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_COLOR; + continue; + } + if (strncmp(argv[n], "-closecolors", 6) == 0) { + valuemask |= XpmCloseness; + view.attributes.closeness = 40000; + continue; + } + if (strcmp(argv[n], "-rgb") == 0) { + if (n < argc - 1) { + valuemask |= XpmRgbFilename; + view.attributes.rgb_fname = argv[++n]; + continue; + } else + Usage(); + + } + if (strncmp(argv[n], "-version", 4) == 0) { + VersionInfo(); + exit(0); + } + if (strcmp(argv[n], "-v") == 0) { + verbose = 1; + continue; + } + if (strcmp(argv[n], "-pcmap") == 0) { + valuemask |= XpmColormap; + continue; + } + Usage(); + } + + XtRealizeWidget(topw); + if (valuemask & XpmColormap) { + colormap = XCreateColormap(dpy, win, + DefaultVisual(dpy, DefaultScreen(dpy)), + AllocNone); + view.attributes.colormap = colormap; + XSetWindowColormap(dpy, win, colormap); + } + view.attributes.colorsymbols = symbols; + view.attributes.numsymbols = numsymbols; + view.attributes.valuemask = valuemask; + +#ifdef Debug + /* this is just to test the XpmCreateDataFromPixmap function */ + + view.attributes.valuemask |= XpmReturnAllocPixels; + view.attributes.valuemask |= XpmReturnExtensions; + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Plaid"); + + ErrorStatus = XpmCreateDataFromPixmap(dpy, &data, view.pixmap, view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Data"); + if (verbose && view.attributes.nextensions) { + unsigned int i, j; + + for (i = 0; i < view.attributes.nextensions; i++) { + fprintf(stderr, "Xpm extension : %s\n", + view.attributes.extensions[i].name); + for (j = 0; j < view.attributes.extensions[i].nlines; j++) + fprintf(stderr, "\t\t%s\n", + view.attributes.extensions[i].lines[j]); + } + } + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.alloc_pixels, + view.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&view.attributes); + view.attributes.valuemask = valuemask; +#endif + + if (input || stdinf) { + view.attributes.valuemask |= XpmReturnInfos; + view.attributes.valuemask |= XpmReturnAllocPixels; + view.attributes.valuemask |= XpmReturnExtensions; + +#ifdef Debug + XpmFree(data); + + /* + * this is just to test the XpmCreatePixmapFromBuffer and + * XpmCreateBufferFromPixmap functions + */ + ErrorStatus = XpmReadFileToBuffer(input, &buffer); + ErrorMessage(ErrorStatus, "CreateBufferFromFile"); + + ErrorStatus = XpmCreatePixmapFromBuffer(dpy, win, buffer, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreatePixmapFromBuffer"); + XpmFree(buffer); + ErrorStatus = XpmCreateBufferFromPixmap(dpy, &buffer, + view.pixmap, view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreateBufferFromPixmap"); + ErrorStatus = XpmWriteFileFromBuffer("buffer_output", buffer); + ErrorMessage(ErrorStatus, "WriteFileFromBuffer"); + XpmFree(buffer); + if (view.pixmap) { + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, view.attributes.alloc_pixels, + view.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&view.attributes); + } + ErrorStatus = XpmReadFileToData(input, &data); + ErrorMessage(ErrorStatus, "ReadFileToData"); + ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreatePixmapFromData"); + ErrorStatus = XpmWriteFileFromData("sxpmout.xpm", data); + ErrorMessage(ErrorStatus, "WriteFileFromData"); + XpmFree(data); + XpmFreeAttributes(&view.attributes); +#endif + ErrorStatus = XpmReadFileToPixmap(dpy, win, input, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Read"); + if (verbose && view.attributes.nextensions) { + unsigned int i, j; + + for (i = 0; i < view.attributes.nextensions; i++) { + fprintf(stderr, "Xpm extension : %s\n", + view.attributes.extensions[i].name); + for (j = 0; j < view.attributes.extensions[i].nlines; j++) + fprintf(stderr, "\t\t%s\n", + view.attributes.extensions[i].lines[j]); + } + } + } else { +#ifdef Debug + ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, + &view.pixmap, &view.mask, + &view.attributes); + XpmFree(data); +#else + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); +#endif + ErrorMessage(ErrorStatus, "Plaid"); + } + if (output || stdoutf) { + ErrorStatus = XpmWriteFileFromPixmap(dpy, output, view.pixmap, + view.mask, &view.attributes); + ErrorMessage(ErrorStatus, "Write"); + } + if (!nod) { + + /* + * manage display if requested + */ + + XSizeHints size_hints; + char *xString = NULL; + + if (w_rtn && h_rtn + && ((w_rtn < view.attributes.width) + || h_rtn < view.attributes.height)) { + resize = 1; + } + if (resize) { + XtResizeWidget(topw, + view.attributes.width, view.attributes.height, 1); + } + if (incResize) { + size_hints.flags = USSize | PMinSize | PResizeInc; + size_hints.height = view.attributes.height; + size_hints.width = view.attributes.width; + size_hints.height_inc = view.attributes.height; + size_hints.width_inc = view.attributes.width; + } else + size_hints.flags = PMinSize; + + size_hints.min_height = view.attributes.height; + size_hints.min_width = view.attributes.width; + XSetWMNormalHints(dpy, win, &size_hints); + + if (input) { + xString = (char *) XtMalloc((sizeof(char) * strlen(input)) + 20); + sprintf(xString, "Sxpm: %s", input); + XStoreName(dpy, win, xString); + XSetIconName(dpy, win, xString); + } else if (stdinf) { + XStoreName(dpy, win, "Sxpm: stdin"); + XSetIconName(dpy, win, "Sxpm: stdin"); + } else { + XStoreName(dpy, win, "Sxpm"); + XSetIconName(dpy, win, "Sxpm"); + } + + XtAddEventHandler(topw, KeyPressMask, False, + (XtEventHandler) kinput, NULL); + XSetWindowBackgroundPixmap(dpy, win, view.pixmap); + + if (view.mask && !nom) + XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, + view.mask, ShapeSet); + + XClearWindow(dpy, win); + XtMapWidget(topw); + if (xString) + XtFree(xString); + XtMainLoop(); + } + Punt(0); + + /* Muffle gcc */ + return 0; +} + +void +Usage() +{ + fprintf(stderr, "\nUsage: %s [options...]\n", command[0]); + fprintf(stderr, "Where options are:\n\ +\n\ +[-d host:display] Display to connect to.\n\ +[-g geom] Geometry of window.\n\ +[-hints] Set ResizeInc for window.\n\ +[-icon filename] Set pixmap for iconWindow.\n\ +[-plaid] Read the included plaid pixmap.\n\ +[filename] Read from file 'filename', and from standard\n\ + input if 'filename' is '-'.\n\ +[-o filename] Write to file 'filename', and to standard\n\ + output if 'filename' is '-'.\n\ +[-pcmap] Use a private colormap.\n\ +[-closecolors] Try to use `close' colors.\n\ +[-nod] Don't display in window.\n\ +[-nom] Don't use clip mask if any.\n\ +[-mono] Use the colors specified for a monochrome visual.\n\ +[-grey4] Use the colors specified for a 4 greyscale visual.\n\ +[-grey] Use the colors specified for a greyscale visual.\n\ +[-color] Use the colors specified for a color visual.\n\ +[-sc symbol color] Override color defaults.\n\ +[-sp symbol pixel] Override color defaults.\n\ +[-cp color pixel] Override color defaults.\n\ +[-rgb filename] Search color names in the rgb text file 'filename'.\n\ +[-v] Verbose - print out extensions.\n\ +[-version] Print out program's version number\n\ + and library's version number if different.\n\ +if no input is specified sxpm reads from standard input.\n\ +\n"); + exit(0); +} + + +void +ErrorMessage(ErrorStatus, tag) + int ErrorStatus; + char *tag; +{ + char *error = NULL; + char *warning = NULL; + + switch (ErrorStatus) { + case XpmSuccess: + return; + case XpmColorError: + warning = "Could not parse or alloc requested color"; + break; + case XpmOpenFailed: + error = "Cannot open file"; + break; + case XpmFileInvalid: + error = "Invalid XPM file"; + break; + case XpmNoMemory: + error = "Not enough memory"; + break; + case XpmColorFailed: + error = "Failed to parse or alloc some color"; + break; + } + + if (warning) + fprintf(stderr, "%s Xpm Warning: %s.\n", tag, warning); + + if (error) { + fprintf(stderr, "%s Xpm Error: %s.\n", tag, error); + Punt(1); + } +} + +void +Punt(i) + int i; +{ + if (icon.pixmap) { + XFreePixmap(dpy, icon.pixmap); + if (icon.mask) + XFreePixmap(dpy, icon.mask); + + XFreeColors(dpy, colormap, + icon.attributes.alloc_pixels, + icon.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&icon.attributes); + } + if (view.pixmap) { + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.alloc_pixels, + view.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&view.attributes); + } + exit(i); +} + +void +kinput(widget, tag, xe, b) + Widget widget; + char *tag; + XEvent *xe; + Boolean *b; +{ + char c = '\0'; + + XLookupString(&(xe->xkey), &c, 1, NULL, NULL); + if (c == 'q' || c == 'Q') + Punt(0); +} + +/* + * small function to extract various version numbers from the given global + * number (following the rule described in xpm.h). + */ +void +GetNumbers(num, format_return, libmajor_return, libminor_return) + int num; + int *format_return; + int *libmajor_return; + char *libminor_return; +{ + *format_return = num / 10000; + *libmajor_return = (num % 10000) / 100; + *libminor_return = 'a' + (num % 10000) % 100 - 1; +} + +void +VersionInfo() +{ + int format, libmajor; + char libminor; + + GetNumbers(XpmIncludeVersion, &format, &libmajor, &libminor); + fprintf(stderr, "sxpm version: %d.%d%c\n", + format, libmajor, libminor); + /* + * if we are linked to an XPM library different from the one we've been + * compiled with, print its own number too. + */ + if (XpmIncludeVersion != XpmLibraryVersion()) { + GetNumbers(XpmLibraryVersion(), &format, &libmajor, &libminor); + fprintf(stderr, "using the XPM library version: %d.%d%c\n", + format, libmajor, libminor); + } +} diff --git a/sxpm/sxpm.man b/sxpm/sxpm.man new file mode 100644 index 0000000..8e5d593 --- /dev/null +++ b/sxpm/sxpm.man @@ -0,0 +1,131 @@ +.\"Copyright (C) 1989-95 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. +.\" +.nr )S 12 +.TH SXPM 1 +.PD +.ad b +.SH NAME +sxpm \- Show an XPM (X PixMap) file and/or convert XPM 1 or 2 files to XPM 3. +.SH SYNOPSIS +\fBsxpm\fR +[\|\fB-d\fR displayname\|] +[\|\fB-g\fR geometry\|] +[\|\fB-hints\fR\|] +[\|\fB-icon\fR filename\|] +[\|\fB-plaid\| | \|\fRfilename\| | \|-\|] +[\|\fB-o\fR filename\| | \|\fB-o\fR -\|] +[\|\fB-pcmap\fR\|] +[\|\fB-closecolors\fR\|] +[\|\fB-nod\fR\|] +[\|\fB-nom\fR\|] +[\|\fB-mono | -grey4 | -grey | -color\fR\|] +[\|\fB-sc\fR symbol color\|] +[\|\fB-sp\fR symbol pixel\|] +[\|\fB-cp\fR color pixel\|] +[\|\fB-rgb\fR filename\|] +[\|\fB-v\fR\|] +.SH DESCRIPTION +.PP +The \fIsxpm\fP program can be used to view any XPM (version 1, 2, or 3) file +and/or to convert a file from XPM1 or XPM2 to XPM version 3. If \fIsxpm\fP is +run with any dummy option specified, the usage is displayed. If no geometry is +specified, the show window will have the size of the read pixmap. Pressing the +key Q in the window will quit the program. +.SH OPTIONS +.TP 8 +.B \-d \fIdisplay\fP +Specifies the display to connect to. +.TP 8 +.B \-g \fIgeom\fP +Window geometry (default is pixmap's size). +.TP 8 +.B \-hints +Set ResizeInc for window. +.TP 8 +.B \-icon \fIfilename\fP +Set icon to pixmap created from the file \fIfilename\fP. +.TP 8 +.B \-plaid +Show the plaid pixmap which is stored as data\fP. +.TP 8 +.B \fIfilename\fP +Read from the file \fIfilename\fP and from standard input if \fIfilename\fP is '-'. +If no input is specified sxpm reads from standard input. +.TP 8 +.B \-o \fIfilename\fP +Write to the file \fIfilename\fP (overwrite if it already exists) and to +standard output if \fIfilename\fP is '-'. +.TP 8 +.B \-mono +Use the colors specified for a monochrome visual. +.TP 8 +.B \-grey4 +Use the colors specified for a 4 color greyscale visual. +.TP 8 +.B \-grey +Use the colors specified for a greyscale visual. +.TP 8 +.B \-color +Use the colors specified for a color visual. +.TP 8 +.B \-pcmap +Use a private colormap. +.TP 8 +.B \-closecolors +Try to use "close colors" before reverting to other visuals. +.TP 8 +.B \-nod +Do not display the pixmap in a window. (Useful when using as converter) +.TP 8 +.B \-nom +Do not use the clipmask if there is any. +.TP 8 +.B \-sc \fIsymbol colorname\fP +Override default color to \fIsymbol\fP to \fIcolorname\fp. +.TP 8 +.B \-sp \fIsymbol pixelvalue\fP +Override default color to \fIsymbol\fP to \fIpixelvalue\fp. +.TP 8 +.B \-cp \fIcolorname pixelvalue\fP +Override default color to \fIcolorname\fP to \fIpixelvalue\fp. +.TP 8 +.B \-rgb \fIfilename\fP +Search color names in the file \fIfilename\fP and write them out instead of +the rgb values. +.TP 8 +.B \-v +Verbose - to print out extensions (stderr). + + +.SH KNOWN BUGS +Some window managers may not accept a pixmap which is not a bitmap as icon +because this does not respect ICCCM, many of the well known ones will accept +it though. + +.SH AUTHOR +Arnaud Le Hors (lehors@sophia.inria.fr) +.br +Bull Research France +.br +Copyright (C) 1989-95 by Groupe Bull. diff --git a/xpm.PS.gz b/xpm.PS.gz new file mode 100644 index 0000000..40e25de Binary files /dev/null and b/xpm.PS.gz differ -- cgit v1.2.1