/*1Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.2All rights reserved.3Copyright (C) 2007-2013, Gabriel Dos Reis.4All rights reserved.56Redistribution and use in source and binary forms, with or without7modification, are permitted provided that the following conditions are8met:910- Redistributions of source code must retain the above copyright11notice, this list of conditions and the following disclaimer.1213- Redistributions in binary form must reproduce the above copyright14notice, this list of conditions and the following disclaimer in15the documentation and/or other materials provided with the16distribution.1718- Neither the name of The Numerical ALgorithms Group Ltd. nor the19names of its contributors may be used to endorse or promote products20derived from this software without specific prior written permission.2122THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS23IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED24TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A25PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER26OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,27EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,28PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR29PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF30LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING31NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33*/3435#include "openaxiom-c-macros.h"3637#include <X11/Xlib.h>38#include <X11/Xutil.h>39#include <X11/Xos.h>40#include <X11/xpm.h>41#include <stdlib.h>42#include <stdio.h>43#include <netinet/in.h>4445#define yes 146#define no 047484950#include "spadcolors.h"51#include "halloc.h"52#include "pixmap.h"53#include "spadcolors.h"54555657/* returns true if the file exists */5859int60file_exists(char *file)61{62FILE *f;6364if ((f = fopen(file, "r")) != NULL) {65fclose(f);66return 1;67}68return 0;69}7071FILE *72zzopen(char *file, const char* mode)73{74char com[512], zfile[512];7576if (file_exists(file))77return fopen(file, mode);78sprintf(zfile, "%s.Z", file);79if (file_exists(zfile)) {80sprintf(com, "gunzip -c %s.Z 2>/dev/null", file);81return popen(com, mode);82}83return NULL;84}85#ifdef OLD8687/*******************************************************************88KF 6/14/9089write_pixmap_file(display, filename, pm, width, height)90and91write_pixmap_file_xy(display, filename, pm, x, y, width, height)92has been merged into one function.9394INPUT: display dsp, screen s, file name fn to write the file in,95window id wid where pixmap is,96upper left corner x, y of original pixmap,97width and height of pixmap98OUTPUT: binary file with data99PURPOSE: write_pixmap_file gets the image structure of the input100pixmap, convert the image data with the permutation color101vector, writes the image structure out to filename.102103Note that writing out a Z pixmap is 8x faster than XY pixmap.104This is because XY writes out each pixel value per plane, thus105number of bits; Z writes out each pixel, or 8 bits at a time.106107The XY format may have been chosen for a reason -- I don't know.108109********************************************************************/110void111write_pixmap_file(Display *dsp, int scr, char *fn,112Window wid, int x, int y, int width,int height)113{114XImage *xi;115FILE *file;116int *permVector;117int num;118int num_colors;119120/* get color map and permutation vector */121if ((num_colors = makePermVector(dsp, scr,(unsigned long **)&permVector)) < 0) {122printf("num_colors < 0!!\n");123exit(-1);124}125126/* reads image structure in ZPixmap format */127xi = XGetImage(dsp, wid, x, y, width, height, AllPlanes, ZPixmap);128file = fopen(fn, "wb");129if (file == NULL) {130perror("opening pixmap file for write");131exit(-1);132}133134#define PUTW(a,b) putw(htonl(a),b)135136137PUTW(xi->width, file);138PUTW(xi->height, file);139PUTW(xi->xoffset, file);140PUTW(xi->format, file);141PUTW(xi->byte_order, file);142PUTW(xi->bitmap_unit, file);143PUTW(xi->bitmap_bit_order, file);144PUTW(xi->bitmap_pad, file);145PUTW(xi->depth, file);146PUTW(xi->bytes_per_line, file);147PUTW(xi->bits_per_pixel, file);148PUTW(xi->red_mask, file);149PUTW(xi->green_mask, file);150PUTW(xi->blue_mask, file);151152num = xi->bytes_per_line * height; /* total number of pixels in pixmap */153154/* store value from permutation */155{156int ii, jj;157158for (ii = 0; ii < width; ii++)159for (jj = 0; jj < height; jj++) {160XPutPixel(xi, ii, jj, permVector[(int) XGetPixel(xi, ii, jj)]);161}162}163fwrite(xi->data, 1, num, file);164fclose(file);165}166167/*******************************************************************168KF 6/14/90169170INPUT: display, screen, filename to read the pixmap data from,171OUTPUT: ximage structure xi, width and height of pixmap172PURPOSE: read_pixmap_file reads an Ximage data structure from173the input file.174This routine can handle pixmaps of both XYPixmap and175ZPixmap. If a pixmap has ZPixmap format, then the image176data, read in as spadColor index, is converted to the177pixel value using spadColor.178179Note that reading in Z format takes less space and time too.180181********************************************************************/182int183read_pixmap_file(Display *display, int screen, char *filename,184XImage **xi, int *width, int *height)185{186FILE *file;187int wi, h, num, num_colors, read_this_time, offset;188Colormap cmap;189int ts;190unsigned long *spadColors;191192/* colormap is necessary to call makeColors */193cmap = DefaultColormap(display, screen);194if ((num_colors = makeColors(display, screen, &cmap, &spadColors, &ts)) < 0) {195return(-1);196}197file = zzopen(filename, "r");198if (file == NULL) {199printf("couldn't open %s\n", filename);200return BitmapOpenFailed;201}202#define GETW(f) ntohl(getw(f))203*width = wi = GETW(file);204*height = h = GETW(file);205(*xi) = XCreateImage(display, DefaultVisual(display, screen),206DisplayPlanes(display, screen),207ZPixmap, 0, NULL, wi, h, 16, 0); /* handles both XY & Z */208if ((*xi) == NULL) {209fprintf(stderr, "Unable to create image\n");210return(-1);211}212(*xi)->width = wi;213(*xi)->height = h;214(*xi)->xoffset = GETW(file);215(*xi)->format = GETW(file);216(*xi)->byte_order = GETW(file);217(*xi)->bitmap_unit = GETW(file);218(*xi)->bitmap_bit_order = GETW(file);219(*xi)->bitmap_pad = GETW(file);220(*xi)->depth = GETW(file);221(*xi)->bytes_per_line = GETW(file);222(*xi)->bits_per_pixel = GETW(file);223(*xi)->red_mask = GETW(file);224(*xi)->green_mask = GETW(file);225(*xi)->blue_mask = GETW(file);226227/* program will bomb if XYPixmap is not allocated enough space */228if ((*xi)->format == XYPixmap) {229/* printf("picture is in XYPixmap format.\n"); */230num = (*xi)->bytes_per_line * h * (*xi)->depth;231}232else /* ZPixmap */233num = (*xi)->bytes_per_line * h;234(*xi)->data = (void*)halloc(num, "Ximage data");235236offset = 0;237while (offset < num) {238read_this_time = fread(((*xi)->data + offset), 1, num - offset, file);239offset = offset + read_this_time;240}241fclose(file);242243/*244* pixmap data in ZPixmap format are spadColor indices; pixmap data in245* XYPixmap format are pixel values246*/247if ((*xi)->format == ZPixmap) {248249int ii, jj;250251for (ii = 0; ii < wi; ii++)252for (jj = 0; jj < h; jj++) {253XPutPixel(*xi, ii, jj, spadColors[(int) XGetPixel(*xi, ii, jj)]);254}255256257}258259return 0;260}261262263#else /*OLD*/264265266267int268read_pixmap_file(Display *display, int screen, char *filename,269XImage **xi, int *width, int *height)270{271XpmAttributes attr;272XImage *xireturn;273274attr.valuemask = 0;275276attr.bitmap_format=ZPixmap; /* instead of XYPixmap */277attr.valuemask |= XpmBitmapFormat;278attr.valuemask |= XpmSize; /* we want feedback on width,height */279attr.valuemask |= XpmCharsPerPixel; /* and cpp */280attr.valuemask |= XpmReturnPixels; /* and pixels, npixels */281attr.valuemask |= XpmReturnAllocPixels; /* and alloc_pixels, nalloc_pixels */282attr.exactColors = False;283attr.valuemask |= XpmExactColors; /* we don't want exact colors*/284attr.closeness = 30000;285attr.valuemask |= XpmCloseness; /* we specify closeness*/286attr.alloc_close_colors = False;287attr.valuemask |= XpmAllocCloseColors; /* we don't allocate close colors*/288289290XpmReadFileToImage(display,filename,xi,&xireturn, &attr );291*width= (*xi)->width;292*height=(*xi)->height;293#ifdef DEBUG294fprintf(stderr,"image file:%s\n",filename);295fprintf(stderr,"\twidth:%d\theight:%d\tcpp:%d\n",attr.width,attr.height,attr.cpp);296fprintf(stderr,"\tused/alloc'ed color pixels:%d/%d\n",attr.npixels,attr.nalloc_pixels);297#endif298return 0;299}300301302void303write_pixmap_file(Display *dsp, int scr, char *fn,304Window wid, int x, int y, int width,int height)305{306XImage *xi;307308/* reads image structure in ZPixmap format */309xi = XGetImage(dsp, wid, x, y, width, height, AllPlanes, ZPixmap);310if (xi==0) return ;311XpmWriteFileFromImage(dsp,fn,xi,0,0);312313}314315316#endif317318319320321322