BRL-CAD
asize.c
Go to the documentation of this file.
1 /* A S I Z E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
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  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup libfb */
21 /** @{ */
22 /** @file ./libfb/asize.c
23  *
24  * Image file AutoSizing code.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include <stdio.h>
32 #include <math.h>
33 #include <sys/stat.h>
34 #include <string.h>
35 
36 #include "fb.h"
37 
38 
39 /* This table does not need to include any square sizes */
40 struct sizes {
41  size_t width; /* image width in pixels */
42  size_t height; /* image height in pixels */
43 };
44 struct sizes fb_common_sizes[] = {
45  { 160, 120 }, /* quarter 640x480 */
46  { 192, 128 }, /* Kodak Photo-CD, level 1, Base/16 */
47  { 320, 200 }, /* PC screen format */
48  { 320, 240 }, /* half 640x480 */
49  { 384, 256 }, /* Kodak Photo-CD, level 2, Base/4 */
50  { 640, 512 }, /* half 1280x1024 */
51  { 640, 400 }, /* PC screen format */
52  { 640, 480 }, /* Common video format */
53  { 640, 485 }, /* Common video format, most correct */
54  { 640, 486 }, /* Common video format */
55  { 720, 485 }, /* Abekas video format, most correct */
56  { 720, 486 }, /* Abekas video format */
57  { 768, 512 }, /* Kodak Photo-CD, level 3, Base */
58  { 1024, 768 }, /* SGI-3D screen size */
59  { 1152, 900 }, /* Sun screen size */
60  { 1280, 960 }, /* twice 640x480 */
61  { 1280, 1024 }, /* SGI-4D screen size */
62  { 1440, 972 }, /* double Abekas video format */
63  { 1536, 1024 }, /* Kodak Photo-CD, level 4, 4*Base */
64  { 1600, 1200 }, /* Digital camera */
65  { 1600, 1280 }, /* Large monitor */
66  { 3072, 2048 }, /* Kodak Photo-CD, level 5, 16*Base */
67  { 3200, 4000 }, /* 8x10 inches, 400 dpi */
68  { 3400, 4400 }, /* 8.5x11 inches, 400 dpi */
69  { 4700, 3300 }, /* A4 size, 11.75x8.25 inches, 400 dpi */
70  { 0, 0 }
71 };
72 
73 
74 /*
75  * If the file name contains size information encoded in it,
76  * then that size is returned, even if it differs from the actual
77  * file dimensions. (It might have been truncated).
78  * Otherwise, the actual file size is passed to fb_common_image_size()
79  * to see if this is a plausible image size.
80  *
81  * Returns -
82  * 0 size unknown
83  * 1 width and height returned
84  */
85 int
86 fb_common_file_size(size_t *widthp, size_t *heightp, const char *filename, int pixel_size)
87 /* pointer to returned width */
88 /* pointer to returned height */
89 /* image file to stat */
90 /* bytes per pixel */
91 {
92  struct stat sbuf;
93  size_t size;
94  register const char *cp;
95 
96  *widthp = *heightp = 0; /* sanity */
97 
98  if (pixel_size <= 0) {
99  return 0;
100  }
101 
102  if (filename == NULL || *filename == '\0') {
103  return 0;
104  }
105 
106  /* Skip over directory names, if any */
107  cp = strchr(filename, '/');
108  if (cp) {
109  cp++; /* skip over slash */
110  } else {
111  cp = filename; /* no slash */
112  }
113 
114  if (fb_common_name_size(widthp, heightp, cp))
115  return 1;
116 
117  if (stat(filename, &sbuf) < 0)
118  return 0;
119 
120  size = (size_t)(sbuf.st_size / pixel_size);
121 
122  return fb_common_image_size(widthp, heightp, size);
123 }
124 
125 
126 /*
127  * Given the number of pixels in an image file, along with a name for the
128  * image (possibly the filename), attempt to determine the
129  * the width and height of the image.
130  *
131  * Returns -
132  * 0 size unknown
133  * 1 width and height returned
134  */
135 
136 int
137 fb_common_name_size(size_t *widthp, size_t *heightp, const char *name)
138 /* pointer to returned width */
139 /* pointer to returned height */
140 /* name to parse */
141 {
142  register const char *cp = name;
143  unsigned long w;
144  unsigned long h;
145 
146  /* File name may have several minus signs in it. Try repeatedly */
147  while (*cp) {
148  cp = strchr(cp, '-'); /* Find a minus sign */
149  if (cp == NULL) break;
150  if (sscanf(cp, "-w%lu-n%lu", &w, &h) == 2) {
151  *widthp = w;
152  *heightp = h;
153  return 1;
154  }
155  cp++; /* skip over the minus */
156  }
157 
158  /* If we got here, we didn't see the answer in the name. */
159  return 0;
160 }
161 
162 
163 /*
164  * Given the number of pixels in an image file,
165  * if this is a "common" image size,
166  * return the width and height of the image.
167  *
168  * Returns -
169  * 0 size unknown
170  * 1 width and height returned
171  */
172 int
173 fb_common_image_size(size_t *widthp, size_t *heightp, size_t npixels)
174 /* pointer to returned width */
175 /* pointer to returned height */
176 /* Number of pixels */
177 {
178  struct sizes *sp;
179  size_t root;
180 
181  if (npixels <= 0)
182  return 0;
183 
184  sp = fb_common_sizes;
185  while (sp->width != 0) {
186  if (npixels == sp->width * sp->height) {
187  *widthp = sp->width;
188  *heightp = sp->height;
189  return 1;
190  }
191  sp++;
192  }
193 
194  /* If the size is a perfect square, then use that. */
195  root = (size_t)(sqrt((double)npixels)+0.999);
196  if (root*root == npixels) {
197  *widthp = root;
198  *heightp = root;
199  return 1;
200  }
201 
202  /* Nope, we are clueless. */
203  return 0;
204 }
205 
206 
207 /*
208  * Local Variables:
209  * mode: C
210  * tab-width: 8
211  * indent-tabs-mode: t
212  * c-file-style: "stroustrup"
213  * End:
214  * ex: shiftwidth=4 tabstop=8
215  */
char filename[MAXLENGTH]
Definition: human.c:105
size_t height
Definition: asize.c:42
size_t width
Definition: asize.c:41
Definition: clone.c:90
Header file for the BRL-CAD common definitions.
Definition: asize.c:40
char * strchr(const char *sp, int c)
struct sizes fb_common_sizes[]
Definition: asize.c:44
int fb_common_name_size(size_t *widthp, size_t *heightp, const char *name)
Definition: asize.c:137
int fb_common_file_size(size_t *widthp, size_t *heightp, const char *filename, int pixel_size)
Definition: asize.c:86
int fb_common_image_size(size_t *widthp, size_t *heightp, size_t npixels)
Definition: asize.c:173