Note: Despite the wide variety of displays and file formats xv deals with, internally it only manipulates either 8-bit colormapped images or 24-bit RGB images. Your Write() routine must be prepared to take either sort of image, and convert it (if necessary) to the image format that your file format dictates.
If you haven't already done so (if/when you created the Load() function):
Make a copy of xvpbm.c , calling it something appropriate. For the rest of this appendix, mentally replace the string ' xvpbm.c ' with the name of your new file.
Edit the Makefile and/or the Imakefile so that your new module will be compiled. In the Makefile , add " xvpbm.o " to the " OBJS = ... " macro definition. In the Imakefile , add " xvpbm.o " to the end of the " OBJS1 = ... " macro definition, and " xvpbm.c" to the end of the "SRCS1 = ..." macro definition.
Edit the new module.
You'll need to #include "xv.h" , of course.
The module should have one externally callable function that does the work of writing the file. The function is called with a large number of arguments, described below. The function should return '0' if everything succeeded, and '-1' on failure.
/*******************************************/ int WritePBM(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,raw,comment) FILE *fp; byte *pic; int ptype, w,h; byte *rmap, *gmap, *bmap; int numcols, colorstyle, raw; char *comment; /*******************************************/
You may pass more parameters, since you're going to be adding the call to this function later on. For example, in my PBM code, I pass one more parameter, 'raw' (whether to save the file as 'raw' or 'ascii') to handle two very similar formats. (Rather than having to write WritePBMRaw() and WritePBMAscii() functions.)
Write the function as you deem appropriate. See xvpbm.c for an example of a Write() routine that writes different formats for 1-bit per pixel images, 8-bit per pixel images, and 24-bit per pixel images, based on ptype and colorstyle .
Note: If your file format can only handle 8-bit images, and ptype is set to PIC24 , you will have to call Conv24to8() to convert the 24-bit image into an 8-bit colormapped image that you can write to the file. See xvgifwr.c for an example of how this is done.
That done, edit ' xv.h ' and add a function declaration for your new function. Search for ' WritePBM() ' in the file for a sample declaration to copy.
Also find the block that begins with:
#define F_GIF 0 #define F_JPEG ( 0 + F_JPGINC)
and add a definition for your format. Note that it'll be easiest to tack it on at the end.
These numbers must be contiguous, as they are used as indices into the fmtMB menu in xvdir.c .
Edit 'xvdir.c'. This is the module that controls the xv save window.
Add another format name, in the appropriate position, to the saveFormats[] string array.
In the function DoSave() , find the following block:
switch (fmt) { case F_GIF: rv = WriteGIF(fp, thepic, ptype, w, h, rp, gp, bp, nc, col, picComments); break; case F_PM: rv = WritePM (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, picComments); break;
and add a case for your function.
Finally, if your format has a common 3 or 4 letter filename suffix (like, ".gif", ".jpg", etc.), you should modify the changeSuffix() routine in xvdir.c so that it recognizes your suffix, and puts your suffix on when someone selects your format.
And It's just that easy!
Okay, maybe it's not that easy...
If your format requires some additional information to specify how the file should be saved (such as the 'quality' setting in JPEG, or position/size parameters in PostScript), then your task is somewhat more difficult. You'll have to create some sort of pop-up dialog box to get the additional information that you want. You'll also have to change the way your Write() function gets called (as it will now get called from your pop-up dialog box). (Though, if you only feel like doing a quick hack, you can probably just use the GetStrPopUp() function to get a one-line character string from the user, and avoid the complication of writing your own dialog box.)
This is not recommended for anyone who doesn't understand Xlib programming. Frankly, it's not recommended for those who do, either, but they at least stand some chance of success.
The more adventurous types who wish to pursue this should take a look at the xvjpeg.c code, which implements an extremely simple pop-up dialog. A considerably more complicated dialog box is implemented in xvps.c. In addition to writing a module like these for your format, you'll also have to add the appropriate hooks to the DoSave() function (in xvdir.c) and the HandleEvent() function (in xvevent.c ). 'grep PS *.c' will be helpful in finding places where the xvps.c module is called.