1 /*
2  * This software is copyrighted as noted below.  It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is".  Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /*
19  * ps.c - interface with the PostScript languaje.
20  *
21  * Author:          J. G. Antuna Roces
22  *                  EECS Department
23  *                  University of Oviedo
24  * Date:            Fri Jan 22 1993
25  * Copyright (c) 1993, J. G. Antuna Roces
26  *
27  *
28  * LUG's Author:    Raul Rivero
29  *                  Mathematics Dept.
30  *                  University of Oviedo
31  * Date:            Wed Feb 17 1993
32  *
33  */
34 
35 #include <lug.h>
36 #include <lugfnts.h>
37 
38 extern int LUGverbose;
39 
write_ps_file(name,image)40 write_ps_file( name, image )
41 char *name;
42 bitmap_hdr *image;
43 {
44   write_ps_file_dimensions( name, image, 19.0, 0.0 );
45 }
46 
write_ps_file_dimensions(name,image,width,length)47 write_ps_file_dimensions( name, image, width, length )
48 char *name;
49 bitmap_hdr *image;
50 double width, length;
51 {
52   ImagenGrisesPs( image->xsize, image->ysize, image->r, 19.0, 27.0, name);
53 }
54 
ImagenGrisesPs(AnchoPix,AltoPix,Datos,Anchura,Altura,Fichero)55 ImagenGrisesPs( AnchoPix, AltoPix, Datos, Anchura, Altura, Fichero )
56 int AnchoPix, AltoPix;
57 unsigned char Datos[];
58 double Anchura, Altura;
59 char *Fichero;
60 /***************************   DOCUMENTACION   *********************************
61 
62    > Implementado el 15 de Enero de 1993 por J. G. Antuna Roces
63    > Modificado el 22 de Enero de 1993 por J. G. Antuna Roces
64         Si no se proporciona la dimension vertical que la imagen final ha de
65         tener, esta se calcula a partir de la dimension horizontal y de la
66         relacion entre el ancho y el alto en pixels de la misma.
67 
68    Parametros de entrada .......................................................
69 
70       AnchoPix : Dimension horizontal en pixels de la imagen a representar
71       AltoPix  : Dimension vertical en pixels de la imagen a representar
72       Datos [] : Tonalidad de gris de cada pixel por filas de arriba a abajo
73       Anchura  : Tamano horizontal de la imagen final en centimetros
74       Altura   : Tamano vertical en centimetros (si es cero, se calcula)
75       Fichero  : Denominacion del fichero PostScript de salida
76 
77    Retorno de la funcion .......................................................
78 
79        1 : Indica exito de la funcion.
80       -1 : Error al intentar abrir el fichero de salida;
81       -2 : Ancho de imagen en centimetros invalida (negativa,nula o muy pequena)
82       -3 : Alto de imagen en centimetros invalida (negativa,nula o muy pequena)
83       -4 : Anchura de imagen en pixels no valida (negativa o nula)
84       -5 : Altura de imagen en pixels no valida (negativa o nula)
85 
86    Descripcion .................................................................
87 
88       Permite obtener un fichero PostScript que generara una imagen a partir
89       de los datos proporcionados mediante los parametros de entrada. Esta
90       imagen se presentara centrada en una pagina DIN A4, en posicion normal
91       o apaisada, en funcion de cual de sus dimensiones sea la mayor (la
92       vertical o la horizontal, respectivamente).
93 
94       La informacion necesaria para generar la imagen, ademas de los tamanos
95       horizontal y vertical que esta ha de tener al ser representada en la
96       pagina, consiste en una secuencia de valores que indican la tonalidad
97       de gris correspondiente a cada uno de los puntos de la misma (un valor
98       entre 0 y 255), descritos de izquierda a derecha y de arriba a abajo,
99       comenzando por la esquina superior izquierda.
100 
101       Es necesario indicar, ademas, la dimension horizontal y vertical en
102       puntos de la imagen a representar y, por supuesto, el numero de valores
103       debera coincidir con el producto de esas dos cantidades.
104 
105       Si como altura final de la imagen a mostrar en la pagina se da un valor
106       nulo, esta se calcula a partir del ancho indicado para la misma, de forma
107       que se mantenga entre ambos valores la relacion existente entre el ancho
108       y el alto de dicha imagen, cuando estos valores se miden en pixels.
109 
110    Implementacion ..............................................................
111 
112       El codigo de la funcion puede considerarse dividido en tres partes. Una
113       primera en la que se verifica  la validez y consistencia de los datos
114       proporcionados mediante los parametros de entrada y se procede al calculo
115       de aquellos valores necesarios para la ejecucion. Una segunda en la que
116       se obtiene el nucleo del codigo fuente PostScript, necesario para la
117       generacion de la imagen y, por ultimo, una tercera parte que proporciona
118       los datos necesarios para la obtencion de la imagen, representados en el
119       formato hexadecimal que requiere el procedimiento PostScript.
120 
121       El codigo fuente PostScript, compactado en lo posible, define una serie
122       de valores que parametrizan la imagen a representar (anchura, altura,
123       posicion,...) junto con la funcion cuya llamada generara dicha imagen a
124       partir de los datos de la misma incluidos en el fichero PostScript.
125 
126 *******************************************************************************/
127 
128 { int NoErr               = 1;  /* Codigos de retorno de la funcion */
129   int ErrFicheroSalida    = -1;
130   int ErrAnchoInvalido    = -2;
131   int ErrAltoInvalido     = -3;
132   int ErrAnchoPixInvalido = -4;
133   int ErrAltoPixInvalido  = -5;
134 
135   int LimiteEscritura = 40;  /* Cuantos valores hexadecimales por linea */
136   int MaxPuntosXPs    = 558; /* Dimensiones de un DIN A4 en PostScript */
137   int MaxPuntosYPs    = 789;
138 
139   int      CoordX;        /* Para situar la imagen en la pagina */
140   int      CoordY;
141   int      SizeX;         /* Para calcular tamano en puntos PostScript */
142   int      SizeY;
143   int      Rotacion;      /* Para girar o no la imagen en la pagina */
144   int      ContEscritura; /* Cuenta datos hexadecimales de cada linea */
145   long int ContLectura;   /* Cuenta el numero de puntos leidos */
146   long int LimiteLectura; /* Maximo de datos hexadecimales por linea */
147   FILE     *Salida;       /* Denominacion del fichero de salida */
148 
149   /* Verifica la validez de los datos obtenidos como parametros de entrada */
150 
151   if ( AnchoPix <= 0 ) return (ErrAnchoPixInvalido);
152   if ( AltoPix <= 0 ) return (ErrAltoPixInvalido);
153   if ( Anchura <= 0.0 ) return (ErrAnchoInvalido);
154   if ( Altura <= 0.0 ) SizeY = (int) (Altura/Anchura*SizeX);
155 
156   /* Calcula las dimensiones de la imagen medidas en puntos PostScript */
157 
158   SizeX = (int) ((Anchura / 2.71) * 72.0);
159   SizeY = (int) ((Altura  / 2.71) * 72.0);
160 
161   if ( SizeX <= 0 ) return (ErrAnchoInvalido);
162   if ( SizeY <= 0 ) return (ErrAltoInvalido);
163 
164   /* Obtiene las coordenadas de la esquina inferior izquierda de la imagen
165      para situar esta en la pagina y verifica si es necesario rotar la misma */
166 
167   if ( SizeX > SizeY )
168     { Rotacion = 90;
169       CoordX = (MaxPuntosXPs - SizeY) / 2 + SizeY;
170       CoordY = (MaxPuntosYPs - SizeX) / 2;
171     }
172   else
173     { Rotacion = 0;
174       CoordX = (MaxPuntosXPs - SizeX) / 2;
175       CoordY = (MaxPuntosYPs - SizeY) / 2;
176     }
177 
178   /* Numero de puntos que forman la imagen */
179 
180   LimiteLectura = (long int)AnchoPix*(long int)AltoPix;
181 
182   /* Abre el fichero de salida PostScript y verifica dicha apertura */
183 
184   Salida = fopen (Fichero,"wb");
185   if ( Salida == NULL ) return (ErrFicheroSalida);
186 
187   /* Codigo fuente en PostScript para la generacion de la imagen */
188 
189   fprintf (Salida,"%%!PS-Adobe-2.0\n");
190   fprintf (Salida,"%%Creator: LUG Library\n");
191   fprintf (Salida,"%%PS converter by J.G.Antuna Roces. @1993\n");
192   fprintf (Salida,"%%EndComments\n\n");
193   fprintf (Salida,"/Px %d def /Py %d def /S Px string def\n",AnchoPix,AltoPix);
194   fprintf (Salida,"/Dib { gsave Px Py 8 [Px 0 0 Py neg 0 Py]\n");
195   fprintf (Salida,"         { currentfile S readhexstring pop } ");
196   fprintf (Salida,"image grestore} def\n");
197   fprintf (Salida,"%d %d translate %d rotate ",CoordX,CoordY,Rotacion);
198   fprintf (Salida,"%d %d scale\n",SizeX,SizeY);
199   fprintf (Salida,"Dib\n");
200 
201   /* Volcado de valores de cada uno de los pixels de la imagen.Se escriben en
202      formato hexadecimal, incluyendo por cada linea <LimiteEscritura> datos   */
203 
204   ContEscritura = 0;
205 
206   for (ContLectura = 0; ContLectura < LimiteLectura; ContLectura++)
207     if ( ++ContEscritura == LimiteEscritura )
208       { ContEscritura = 0;
209         fprintf(Salida,"%02x\n",Datos [ContLectura]);
210       }
211     else fprintf (Salida,"%02x",Datos [ContLectura]);
212 
213   /* Anade el comando <showpage> (sin el no se ve la imagen) y cierra fichero */
214 
215   fprintf (Salida,"\nshowpage\n");
216   fclose (Salida);
217   return (NoErr);
218 };
219