PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/brlcad/branches/bottie/src/util/pixcut.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 380 lines | 274 code | 25 blank | 81 comment | 69 complexity | a851b941cb84e92296dd8c44d48cbe00 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /* P I X C U T . C
  2. * BRL-CAD
  3. *
  4. * Copyright (c) 2004-2011 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. /** @file pixcut.c
  21. *
  22. * Extract a piece of a pix file. If the parameters of the file to be
  23. * extracted do not fit within the original pix file then the extra area is
  24. * filled with a background solid color.
  25. *
  26. * Author -
  27. * Christopher T. Johnson
  28. * September 12, 1992
  29. *
  30. * This software is Copyright (C) 1992 by Paladin Software.
  31. * All rights reserved.
  32. */
  33. #include "common.h"
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include "bio.h"
  37. #include "bu.h"
  38. #include "vmath.h"
  39. #include "bn.h"
  40. #include "fb.h"
  41. static long int org_width = 512L; /* Default file sizes 512x512 */
  42. static long int org_height = 512L;
  43. static long int new_width = 512L;
  44. static long int new_height = 512L;
  45. static long int base_x = 0; /* Default to lower left corner */
  46. static long int base_y = 0;
  47. static int Verbose = 0;
  48. static long int num_bytes = 3L;
  49. #define SIZEBACK 256
  50. static unsigned char background[SIZEBACK]; /* Holds the fill background color */
  51. static char stdiobuf[4*1024*1024] = {0};
  52. static FILE *input = (FILE *)NULL;
  53. static char *in_name = (char *)NULL;
  54. static int autosize = 0;
  55. static int isfile = 0;
  56. static char usage[] = "\
  57. pixcut: Copyright (C) 1992 Paladin Software\n\
  58. pixcut: All rights reserved\n\
  59. pixcut: Usage: [-v] [-h] [-H] [-a] [-# num_bytes] [-C red/green/blue]\n\
  60. [-s in_square_size] [-w in_width] [-n in_height]\n\
  61. [-S out_square_size] [-W out_width] [-N out_height]\n\
  62. [-x horizontal] [-y vertical] [file_in]\n";
  63. void
  64. parse_color(unsigned char *bak, char *s)
  65. {
  66. int red, green, blue;
  67. int result;
  68. result = sscanf(s, "%d/%d/%d", &red, &green, &blue);
  69. if (result != 3) return;
  70. bak[0] = red;
  71. bak[1] = green;
  72. bak[2] = blue;
  73. }
  74. int
  75. get_args(int argc, char **argv)
  76. {
  77. int c;
  78. while ((c = bu_getopt(argc, argv, "vahHC:s:w:n:S:W:N:x:y:#:")) != EOF) {
  79. switch (c) {
  80. case 'v':
  81. Verbose = 1;
  82. break;
  83. case 'a':
  84. autosize = 1;
  85. break;
  86. case 'h':
  87. org_width = org_height = 1024L;
  88. autosize = 0;
  89. break;
  90. case 'H':
  91. new_width = new_height = 1024L;
  92. break;
  93. case 's':
  94. org_width = org_height = atol(bu_optarg);
  95. autosize = 0;
  96. break;
  97. case 'S':
  98. new_width = new_height = atol(bu_optarg);
  99. break;
  100. case 'w':
  101. org_width = atol(bu_optarg);
  102. autosize = 0;
  103. break;
  104. case 'W':
  105. new_width = atol(bu_optarg);
  106. break;
  107. case 'n':
  108. org_height = atol(bu_optarg);
  109. autosize = 0;
  110. break;
  111. case 'N':
  112. new_height = atol(bu_optarg);
  113. break;
  114. case 'x':
  115. base_x = atol(bu_optarg);
  116. break;
  117. case 'y':
  118. base_y = atol(bu_optarg);
  119. break;
  120. case 'C':
  121. parse_color(background, bu_optarg);
  122. break;
  123. case '#':
  124. num_bytes = atol(bu_optarg);
  125. break;
  126. default: /* '?' */
  127. return 0;
  128. }
  129. }
  130. if (bu_optind >= argc) {
  131. if (isatty(fileno(stdin))) return 0;
  132. in_name = "-";
  133. input = stdin;
  134. } else {
  135. in_name = argv[bu_optind];
  136. if (BU_STR_EQUAL(in_name, "-")) {
  137. if (isatty(fileno(stdin))) return 0;
  138. input = stdin;
  139. } else {
  140. if ((input = fopen(in_name, "r")) == NULL) {
  141. perror(in_name);
  142. (void)fprintf(stderr,
  143. "pixcut: cannot open \"%s\" for reading\n",
  144. in_name);
  145. return 0;
  146. }
  147. isfile = 1;
  148. }
  149. }
  150. if (argc > ++bu_optind) {
  151. (void)fprintf(stderr, "pixcut: excess argument(s) ignored\n");
  152. }
  153. return 1; /* OK */
  154. }
  155. int
  156. main(int argc, char **argv)
  157. {
  158. unsigned char *inbuf, *outbuf;
  159. unsigned char *buffer;
  160. long int i;
  161. unsigned char *cp;
  162. int finish, row, result;
  163. for (i=0;i<SIZEBACK;i++) background[i] = 0;
  164. background[2] = 1;
  165. if (!get_args(argc, argv)) {
  166. (void)fprintf(stderr, "%s", usage);
  167. bu_exit (1, NULL);
  168. }
  169. /* Should we autosize the input? */
  170. if (isfile && autosize) {
  171. size_t w, h;
  172. if (fb_common_file_size(&w, &h, in_name, num_bytes)) {
  173. org_width = (long)w;
  174. org_height = (long)h;
  175. } else {
  176. (void) fprintf(stderr, "pixcut: unable to autosize\n");
  177. }
  178. }
  179. /*
  180. * On the assumption that there will be lots more input to paw
  181. * through than there will be output to write, give STDIO a
  182. * big input buffer to allow decent sized transfers from the
  183. * filesystem.
  184. */
  185. (void)setvbuf(input, stdiobuf, _IOFBF, sizeof(stdiobuf));
  186. /*
  187. * Make a buffer will hold a single scan line of assuming a worst
  188. * case cut of 1 pixel of the edge.
  189. */
  190. buffer = (unsigned char *)bu_malloc((org_width+new_width)*num_bytes, "buffer");
  191. /*
  192. * Spew at the user if they asked.
  193. */
  194. if (Verbose) {
  195. (void)fprintf(stderr, "pixcut: Copyright (C) 1992 Paladin Software\n");
  196. (void)fprintf(stderr, "pixcut: All rights reserved.\npixcut:\n");
  197. (void)fprintf(stderr, "pixcut: original image %ldx%ld\n",
  198. org_width, org_height);
  199. (void)fprintf(stderr, "pixcut: new image %ldx%ld\n",
  200. new_width, new_height);
  201. (void)fprintf(stderr, "pixcut: offset %ldx%ld\n", base_x, base_y);
  202. (void)fprintf(stderr, "pixcut: background color %d/%d/%d\n",
  203. background[0], background[1], background[2]);
  204. if (base_x < 0 || base_y < 0 ||
  205. base_x+new_width >org_width ||
  206. base_y+new_height > org_height) {
  207. int comma=0;
  208. char *last = 0;
  209. (void) fprintf(stderr,
  210. "pixcut: adding background strip on the");
  211. if (base_x < 0) {
  212. last = "left";
  213. }
  214. if (base_y < 0) {
  215. if (last) {
  216. (void) fprintf(stderr, " %s", last);
  217. comma=1;
  218. }
  219. last = "bottom";
  220. }
  221. if (base_x+new_width >org_width) {
  222. if (last) {
  223. if (comma) {
  224. (void)fprintf(stderr, ", %s", last);
  225. } else {
  226. (void)fprintf(stderr, " %s", last);
  227. }
  228. comma=1;
  229. }
  230. }
  231. if (base_y+new_height > org_height) {
  232. if (last) {
  233. if (comma) {
  234. (void)fprintf(stderr, ", %s", last);
  235. } else {
  236. (void)fprintf(stderr, " %s", last);
  237. }
  238. comma = 1;
  239. }
  240. last = "top";
  241. }
  242. if (comma) {
  243. (void)fprintf(stderr, " and %s.\n", last);
  244. } else {
  245. (void)fprintf(stderr, " %s.\n", last);
  246. }
  247. }
  248. }
  249. /*
  250. * If the new image does not intersect the original, then set the base_x
  251. * so that it does not overlap the original but at the same time minmizes
  252. * the memory hit.
  253. */
  254. if (base_x + new_width < 0 || base_x > org_width) {
  255. base_x = org_width;
  256. }
  257. /*
  258. * Assign the inbuf and outbuf pointers so that reads and writes take place
  259. * from a consistent location.
  260. */
  261. if (base_x < 0) {
  262. outbuf = buffer;
  263. inbuf = buffer - base_x*num_bytes; /* base_x < 0 so - not + */
  264. } else {
  265. outbuf = buffer + base_x*num_bytes;
  266. inbuf = buffer;
  267. }
  268. /*
  269. * Now fill the output buffer with the background color if needed.
  270. */
  271. if (base_x < 0 || base_y < 0 || base_x+new_width > org_width) {
  272. for (i=0, cp = outbuf; i<new_width; i++, cp+=num_bytes) {
  273. long int jj;
  274. for (jj=0; jj<num_bytes && jj<SIZEBACK; jj++) {
  275. cp[jj]=background[jj];
  276. }
  277. }
  278. }
  279. finish = base_y + new_height;
  280. if (base_y < 0) {
  281. row = base_y;
  282. } else {
  283. row = 0;
  284. }
  285. /*
  286. * Now sync the input file to the output file.
  287. */
  288. while (row < 0 && row < finish) {
  289. result = fwrite(outbuf, num_bytes, new_width, stdout);
  290. if (result != new_width) {
  291. perror("pixcut: fwrite");
  292. bu_exit (3, NULL);
  293. }
  294. row++;
  295. }
  296. while (row < base_y) {
  297. result = fread(inbuf, num_bytes, org_width, input);
  298. row++;
  299. }
  300. /*
  301. * At this point "row" is an index into the original file.
  302. */
  303. while (row < finish && row < org_height) {
  304. result = fread(inbuf, num_bytes, org_width, input);
  305. if (result != org_width) {
  306. for (cp=inbuf+result*num_bytes; result < org_width; cp+=num_bytes, ++result) {
  307. long int jj;
  308. for (jj=0; jj<num_bytes && jj<SIZEBACK; jj++) {
  309. cp[jj] = background[jj];
  310. }
  311. }
  312. org_height = row-1;
  313. }
  314. result = fwrite(outbuf, num_bytes, new_width, stdout);
  315. if (result != new_width) {
  316. perror("pixcut: fwrite");
  317. bu_exit (3, NULL);
  318. }
  319. row++;
  320. }
  321. /*
  322. * Refill the output buffer if we are going to be outputing background
  323. * lines.
  324. */
  325. if (row >= org_height) {
  326. for (cp=outbuf, i=0;i<new_width;cp+=num_bytes, i++) {
  327. long int jj;
  328. for (jj=0; jj<num_bytes && jj<SIZEBACK;jj++) {
  329. cp[jj] = background[jj];
  330. }
  331. }
  332. }
  333. /*
  334. * We've taken all we can from the input file, now it's time to
  335. * output the remaining background lines (if any).
  336. */
  337. while (row < finish) {
  338. result = fwrite(outbuf, num_bytes, new_width, stdout);
  339. if (result != new_width) {
  340. perror("pixcut: fwrite");
  341. bu_exit (3, NULL);
  342. }
  343. row++;
  344. }
  345. return 0;
  346. }
  347. /*
  348. * Local Variables:
  349. * mode: C
  350. * tab-width: 8
  351. * indent-tabs-mode: t
  352. * c-file-style: "stroustrup"
  353. * End:
  354. * ex: shiftwidth=4 tabstop=8
  355. */