1 /* pnmtile.c - replicate a portable anymap into a specified size
2 **
3 ** Copyright (C) 1989 by Jef Poskanzer.
4 **
5 ** Permission to use, copy, modify, and distribute this software and its
6 ** documentation for any purpose and without fee is hereby granted, provided
7 ** that the above copyright notice appear in all copies and that both that
8 ** copyright notice and this permission notice appear in supporting
9 ** documentation. This software is provided "as is" without express or
10 ** implied warranty.
11 */
12
13 #include "pm_c_util.h"
14 #include "mallocvar.h"
15 #include "shhopt.h"
16 #include "pnm.h"
17
18
19
20 struct cmdlineInfo {
21 /* All the information the user supplied in the command line,
22 in a form easy for the program to use.
23 */
24 const char * inputFileName;
25 unsigned int width;
26 unsigned int height;
27 };
28
29
30
31 static void
parseCommandLine(int argc,const char ** argv,struct cmdlineInfo * const cmdlineP)32 parseCommandLine(int argc, const char ** argv,
33 struct cmdlineInfo * const cmdlineP) {
34 /*----------------------------------------------------------------------------
35 Note that the file spec array we return is stored in the storage that
36 was passed to us as the argv array.
37 -----------------------------------------------------------------------------*/
38 optEntry *option_def;
39 /* Instructions to OptParseOptions3 on how to parse our options.
40 */
41 optStruct3 opt;
42
43 unsigned int option_def_index;
44
45 MALLOCARRAY_NOFAIL(option_def, 100);
46
47 option_def_index = 0; /* incremented by OPTENT3 */
48
49 opt.opt_table = option_def;
50 opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */
51 opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */
52
53 OPTENTINIT;
54
55 pm_optParseOptions3(&argc, (char**)argv, opt, sizeof opt, 0);
56 /* Uses and sets argc, argv, and some of *cmdlineP and others. */
57
58 if (argc-1 < 2)
59 pm_error("You must specify at least two parameters: "
60 "width and height. You specified %u",
61 argc-1);
62 else {
63 cmdlineP->width = pm_parse_width(argv[1]);
64 cmdlineP->height = pm_parse_height(argv[2]);
65
66 if (argc-1 > 2) {
67 cmdlineP->inputFileName = argv[3];
68
69 if (argc-1 > 3)
70 pm_error("There are at most three arguments: "
71 "width, height, file name. You specified %u",
72 argc-1);
73 } else
74 cmdlineP->inputFileName = "-";
75 }
76 }
77
78
79
80 int
main(int argc,const char ** argv)81 main(int argc, const char ** argv) {
82
83 struct cmdlineInfo cmdline;
84 FILE * ifP;
85 xel ** xels;
86 xel * xelrow;
87 xelval maxval;
88 int rows, cols;
89 int format;
90 unsigned int row;
91
92 pm_proginit(&argc, argv);
93
94 parseCommandLine(argc, argv, &cmdline);
95
96 ifP = pm_openr(cmdline.inputFileName);
97
98 xels = pnm_readpnm(ifP, &cols, &rows, &maxval, &format);
99 pm_close(ifP);
100
101 xelrow = pnm_allocrow(cmdline.width);
102
103 pnm_writepnminit(stdout, cmdline.width, cmdline.height, maxval, format, 0);
104 for (row = 0; row < cmdline.height; ++row) {
105 unsigned int col;
106 for (col = 0; col < cmdline.width; ++col)
107 xelrow[col] = xels[row % rows][col % cols];
108 pnm_writepnmrow(stdout, xelrow, cmdline.width, maxval, format, 0);
109 }
110
111 pm_close(stdout);
112
113 return 0;
114 }
115