GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/nrrd/formatEPS.c Lines: 1 94 1.1 %
Date: 2017-05-26 Branches: 0 38 0.0 %

Line Branch Exec Source
1
/*
2
  Teem: Tools to process and visualize scientific data and images             .
3
  Copyright (C) 2013, 2012, 2011, 2010, 2009  University of Chicago
4
  Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5
  Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
6
7
  This library is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU Lesser General Public License
9
  (LGPL) as published by the Free Software Foundation; either
10
  version 2.1 of the License, or (at your option) any later version.
11
  The terms of redistributing and/or modifying this software also
12
  include exceptions to the LGPL that facilitate static linking.
13
14
  This library is distributed in the hope that it will be useful,
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
  Lesser General Public License for more details.
18
19
  You should have received a copy of the GNU Lesser General Public License
20
  along with this library; if not, write to Free Software Foundation, Inc.,
21
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
*/
23
24
#include "nrrd.h"
25
#include "privateNrrd.h"
26
27
static int
28
_nrrdFormatEPS_available(void) {
29
30
  /* but only for writing ... */
31
4
  return AIR_TRUE;
32
}
33
34
static int
35
_nrrdFormatEPS_nameLooksLike(const char *filename) {
36
37
  return airEndsWith(filename, NRRD_EXT_EPS);
38
}
39
40
static int
41
_nrrdFormatEPS_fitsInto(const Nrrd *nrrd, const NrrdEncoding *encoding,
42
                        int useBiff) {
43
  static const char me[]="_nrrdFormatEPS_fitsInto";
44
  int ret;
45
46
  AIR_UNUSED(encoding);
47
  /* encoding information is ignored- its always going to be hex */
48
  if (!nrrd) {
49
    biffMaybeAddf(useBiff, NRRD, "%s: got NULL nrrd (%p)",
50
                  me, AIR_CVOIDP(nrrd));
51
    return AIR_FALSE;
52
  }
53
  if (nrrdTypeUChar != nrrd->type) {
54
    biffMaybeAddf(useBiff, NRRD, "%s: type must be %s (not %s)", me,
55
                  airEnumStr(nrrdType, nrrdTypeUChar),
56
                  airEnumStr(nrrdType, nrrd->type));
57
    return AIR_FALSE;
58
  }
59
  if (2 == nrrd->dim) {
60
    /* its a gray-scale image */
61
    ret = 2;
62
  } else if (3 == nrrd->dim) {
63
    if (1 == nrrd->axis[0].size) {
64
      /* its a faux-3D image, really grayscale */
65
      ret = 2;
66
    } else if (3 == nrrd->axis[0].size) {
67
      /* its a real RGB color image */
68
      ret = 3;
69
    } else if (4 == nrrd->axis[0].size) {
70
      /* its a real CMYK (our best guess) color image */
71
      ret = 3;
72
    } else {
73
      /* else its no good */
74
      char stmp[AIR_STRLEN_SMALL];
75
      biffMaybeAddf(useBiff, NRRD,
76
                    "%s: dim is 3, but 1st axis size is %s, not 1, 3, or 4",
77
                    me, airSprintSize_t(stmp, nrrd->axis[0].size));
78
      return AIR_FALSE;
79
    }
80
  } else {
81
    biffMaybeAddf(useBiff, NRRD, "%s: dimension is %d, not 2 or 3",
82
                  me, nrrd->dim);
83
    return AIR_FALSE;
84
  }
85
  return ret;
86
}
87
88
static int
89
_nrrdFormatEPS_contentStartsLike(NrrdIoState *nio) {
90
91
  AIR_UNUSED(nio);
92
  /* this is a write-only format */
93
  return AIR_FALSE;
94
}
95
96
static int
97
_nrrdFormatEPS_read(FILE *file, Nrrd *nrrd, NrrdIoState *nio) {
98
  static const char me[]="_nrrdFormatEPS_read";
99
100
  AIR_UNUSED(file);
101
  AIR_UNUSED(nrrd);
102
  AIR_UNUSED(nio);
103
  biffAddf(NRRD, "%s: sorry, this is a write-only format", me);
104
  return 1;
105
}
106
107
static int
108
_nrrdFormatEPS_write(FILE *file, const Nrrd *_nrrd, NrrdIoState *nio) {
109
  static const char me[]="_nrrdFormatEPS_write";
110
  int color, cmyk, sx, sy;
111
  Nrrd *nrrd;
112
  double aspect, minX, minY, maxX, maxY, scale;
113
  airArray *mop;
114
115
  mop = airMopNew();
116
  airMopAdd(mop, nrrd = nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
117
  if (nrrdCopy(nrrd, _nrrd)) {
118
    biffAddf(NRRD, "%s: couldn't make private copy", me);
119
    airMopError(mop); return 1;
120
  }
121
  if (3 == nrrd->dim && 1 == nrrd->axis[0].size) {
122
    if (nrrdAxesDelete(nrrd, nrrd, 0)) {
123
      biffAddf(NRRD, "%s:", me);
124
      airMopError(mop); return 1;
125
    }
126
  }
127
  color = (3 == nrrd->dim) && (3 == nrrd->axis[0].size
128
                               || 4 == nrrd->axis[0].size);
129
  cmyk = color && 4 == nrrd->axis[0].size;
130
  if (color) {
131
    sx = AIR_CAST(int, nrrd->axis[1].size);
132
    sy = AIR_CAST(int, nrrd->axis[2].size);
133
  } else {
134
    sx = AIR_CAST(int, nrrd->axis[0].size);
135
    sy = AIR_CAST(int, nrrd->axis[1].size);
136
  }
137
  aspect = AIR_CAST(double, sx)/sy;
138
  if (aspect > 7.5/10) {
139
    /* image has a wider aspect ratio than safely printable page area */
140
    minX = 0.5;
141
    maxX = 8.0;
142
    minY = 5.50 - 7.5*sy/sx/2;
143
    maxY = 5.50 + 7.5*sy/sx/2;
144
    scale = 7.5/sx;
145
  } else {
146
    /* image is taller ... */
147
    minX = 4.25 - 10.0*sx/sy/2;
148
    maxX = 4.25 + 10.0*sx/sy/2;
149
    minY = 0.5;
150
    maxY = 10.5;
151
    scale = 10.0/sy;
152
  }
153
  minX *= 72; minY *= 72;
154
  maxX *= 72; maxY *= 72;
155
  scale *= 72;
156
157
  fprintf(file, "%%!PS-Adobe-3.0 EPSF-3.0\n");
158
  fprintf(file, "%%%%Creator: Nrrd Utilities From the "
159
          "Great Nation of Deseret\n");
160
  fprintf(file, "%%%%Title: %s\n",
161
          nrrd->content ? nrrd->content : "A lovely little image");
162
  fprintf(file, "%%%%Pages: 1\n");
163
  fprintf(file, "%%%%BoundingBox: %d %d %d %d\n",
164
          (int)floor(minX), (int)floor(minY),
165
          (int)ceil(maxX), (int)ceil(maxY));
166
  fprintf(file, "%%%%HiResBoundingBox: %g %g %g %g\n",
167
          minX, minY, maxX, maxY);
168
  fprintf(file, "%%%%EndComments\n");
169
  fprintf(file, "%%%%BeginProlog\n");
170
  fprintf(file, "%% linestr creates an empty string to hold "
171
          "one scanline\n");
172
  fprintf(file, "/linestr %d string def\n", sx*(color
173
                                                ? (cmyk
174
                                                   ? 4
175
                                                   : 3)
176
                                                : 1));
177
  fprintf(file, "%%%%EndProlog\n");
178
  fprintf(file, "%%%%Page: 1 1\n");
179
  fprintf(file, "gsave\n");
180
  fprintf(file, "%g %g moveto\n", minX, minY);
181
  fprintf(file, "%g %g lineto\n", maxX, minY);
182
  fprintf(file, "%g %g lineto\n", maxX, maxY);
183
  fprintf(file, "%g %g lineto\n", minX, maxY);
184
  fprintf(file, "closepath\n");
185
  fprintf(file, "clip\n");
186
  fprintf(file, "gsave newpath\n");
187
  fprintf(file, "%g %g translate\n", minX, minY);
188
  fprintf(file, "%g %g scale\n", sx*scale, sy*scale);
189
  fprintf(file, "%d %d 8\n", sx, sy);
190
  fprintf(file, "[%d 0 0 -%d 0 %d]\n", sx, sy, sy);
191
  if (color) {
192
    fprintf(file, "{currentfile linestr readhexstring pop} "
193
            "false %d colorimage\n", cmyk ? 4 : 3);
194
  } else {
195
    fprintf(file, "{currentfile linestr readhexstring pop} image\n");
196
  }
197
  nrrdEncodingHex->write(file, nrrd->data, nrrdElementNumber(nrrd),
198
                         nrrd, nio);
199
  fprintf(file, "\n");
200
  fprintf(file, "grestore\n");
201
  fprintf(file, "grestore\n");
202
203
  airMopError(mop);
204
  return 0;
205
}
206
207
const NrrdFormat
208
_nrrdFormatEPS = {
209
  "EPS",
210
  AIR_FALSE,  /* isImage */
211
  AIR_FALSE,  /* readable */
212
  AIR_FALSE,  /* usesDIO */
213
  _nrrdFormatEPS_available,
214
  _nrrdFormatEPS_nameLooksLike,
215
  _nrrdFormatEPS_fitsInto,
216
  _nrrdFormatEPS_contentStartsLike,
217
  _nrrdFormatEPS_read,
218
  _nrrdFormatEPS_write
219
};
220
221
const NrrdFormat *const
222
nrrdFormatEPS = &_nrrdFormatEPS;