SDDSlib
Loading...
Searching...
No Matches
sdds2tiff.c File Reference

Converts SDDS files to TIFF images. More...

#include "tiffio.h"
#include "SDDS.h"
#include "mdb.h"
#include "scan.h"

Go to the source code of this file.

Enumerations

enum  option_type {
  OPT_MAXCONTRAST , OPT_FROMPAGE , OPT_TOPAGE , OPT_COLUMNPREFIX ,
  OPT_PIPE , OPT_16BIT , N_OPTIONS
}
 

Functions

int main (int argc, char *argv[])
 

Variables

static char * option [N_OPTIONS]
 
static char * USAGE
 

Detailed Description

Converts SDDS files to TIFF images.

This program reads data from an SDDS (Self Describing Data Set) file and generates TIFF images. It supports various options for processing pages, specifying data columns, and adjusting the output format (e.g., 16-bit depth, maximum contrast).

Features:

  • Processes multiple pages of an SDDS file.
  • Converts each page to a separate TIFF image.
  • Supports 8-bit and 16-bit output formats.
  • Allows customization of column prefixes for line data.
  • Adjusts image contrast based on input data.

Usage:

sdds2tiff [-pipe[=input]] <input> <output>
[-fromPage=<pageNumber>] [-toPage=<pageNumber>]
[-columnPrefix=<Line>] [-maxContrast] [-16bit]

Input File Styles:

  1. Single column SDDS file with Variable1Name and Variable2Name parameters, along with <Variable1Name>Dimension and <Variable2Name>Dimension parameters.
  2. A file containing multiple columns prefixed with a specified string (e.g., Line*).

Each page in the input file is converted to a separate TIFF image, named <output>.%04ld.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday, M. Borland

Definition in file sdds2tiff.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 47 of file sdds2tiff.c.

47 {
48 OPT_MAXCONTRAST,
49 OPT_FROMPAGE,
50 OPT_TOPAGE,
51 OPT_COLUMNPREFIX,
52 OPT_PIPE,
53 OPT_16BIT,
54 N_OPTIONS
55} option_type;

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 77 of file sdds2tiff.c.

77 {
78 SDDS_DATASET SDDS_dataset;
79 SCANNED_ARG *s_arg;
80 TIFF *tif;
81 char **columnNames = NULL;
82 char *input = NULL, *output = NULL;
83 char *columnPrefix = NULL;
84 char *buffer = NULL, *outputName = NULL;
85 uint16_t *buffer16 = NULL;
86 int32_t **data = NULL;
87 long j;
88 long bit16 = 0;
89 long linesFound = 0;
90 int64_t i, k;
91 int64_t rows = 0;
92 int32_t nColumns = 0;
93 long maxvalue = 0;
94 long page = 1;
95 long index = 1;
96 long fromPage = 0;
97 long toPage = 0;
98 int maxContrast = 0;
99 double div = 1;
100 char *xVar = NULL, *yVar = NULL;
101 char zColumnName[40];
102 char xDimName[40], yDimName[40];
103 int64_t xDim;
104 int32_t yDim;
105 long style = 1;
106 unsigned long pipeFlags = 0;
107 long maxPossibleLong = 255;
108 double maxPossible = maxPossibleLong;
109
110 /* Register program name */
112
113 /* Process arguments */
114 argc = scanargs(&s_arg, argc, argv);
115 if (argc < 3) {
116 fprintf(stderr, "%s", USAGE);
117 return 1;
118 }
119
120 /* Parse options */
121 for (i = 1; i < argc; i++) {
122 if (s_arg[i].arg_type == OPTION) {
123 switch (match_string(s_arg[i].list[0], option, N_OPTIONS, 0)) {
124 case OPT_MAXCONTRAST:
125 maxContrast = 1;
126 break;
127 case OPT_FROMPAGE:
128 if (s_arg[i].n_items < 2) {
129 SDDS_Bomb("invalid -fromPage syntax");
130 }
131 if (sscanf(s_arg[i].list[1], "%ld", &fromPage) != 1 || fromPage <= 0) {
132 SDDS_Bomb("invalid -fromPage syntax or value");
133 }
134 break;
135 case OPT_TOPAGE:
136 if (s_arg[i].n_items < 2) {
137 SDDS_Bomb("invalid -toPage syntax");
138 }
139 if (sscanf(s_arg[i].list[1], "%ld", &toPage) != 1 || toPage <= 0) {
140 SDDS_Bomb("invalid -toPage syntax or value");
141 }
142 break;
143 case OPT_COLUMNPREFIX:
144 if (s_arg[i].n_items < 2) {
145 SDDS_Bomb("invalid -columnPrefix syntax");
146 }
147 SDDS_CopyString(&columnPrefix, s_arg[i].list[1]);
148 break;
149 case OPT_PIPE:
150 if (!processPipeOption(s_arg[i].list + 1, s_arg[i].n_items - 1, &pipeFlags)) {
151 fprintf(stderr, "invalid -pipe syntax\n");
152 return 1;
153 }
154 break;
155 case OPT_16BIT:
156 bit16 = 1;
157 maxPossible = maxPossibleLong = 65535;
158 break;
159 default:
160 fprintf(stderr, "sdds2tiff: invalid option seen\n%s", USAGE);
161 return 1;
162 }
163 } else {
164 if (!input) {
165 SDDS_CopyString(&input, s_arg[i].list[0]);
166 } else if (!output) {
167 SDDS_CopyString(&output, s_arg[i].list[0]);
168 } else {
169 fprintf(stderr, "sdds2tiff: too many filenames\n%s", USAGE);
170 return 1;
171 }
172 }
173 }
174
175 if (fromPage && toPage && fromPage > toPage) {
176 SDDS_Bomb("invalid -fromPage and -toPage");
177 }
178
179 if (!columnPrefix) {
180 columnPrefix = malloc(5 * sizeof(char));
181 sprintf(columnPrefix, "Line");
182 }
183
184 if (pipeFlags & USE_STDIN) {
185 processFilenames("sdds2tiff", &input, &output, USE_STDIN, 1, NULL);
186 }
187 if (!SDDS_InitializeInput(&SDDS_dataset, input)) {
188 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
189 }
190
191 outputName = malloc((strlen(output) + 10) * sizeof(char));
192
193 /* Check required parameters */
194 if (SDDS_CheckParameter(&SDDS_dataset, "Variable1Name", NULL, SDDS_STRING, NULL) != SDDS_CHECK_OKAY) {
195 style = 2;
196 }
197 if (SDDS_CheckParameter(&SDDS_dataset, "Variable2Name", NULL, SDDS_STRING, NULL) != SDDS_CHECK_OKAY) {
198 style = 2;
199 }
200
201 columnNames = SDDS_GetColumnNames(&SDDS_dataset, &nColumns);
202 if (!columnNames) {
203 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
204 }
205
206 /* Handle different styles */
207 if (style == 1) {
208 if (nColumns != 1) {
209 fprintf(stderr, "sdds2tiff: Expected one column but found more than one\n");
210 return 1;
211 }
212 sprintf(zColumnName, "%s", columnNames[0]);
213 } else if (style == 2) {
214 for (i = 0; i < nColumns; i++) {
215 if (strncmp(columnPrefix, columnNames[i], strlen(columnPrefix)) == 0) {
216 linesFound++;
217 }
218 }
219 if (linesFound == 0) {
220 fprintf(stderr, "sdds2tiff: No columns found named %s*\n", columnPrefix);
221 return 1;
222 }
223 data = malloc(linesFound * sizeof(*data));
224 }
225
226 /* Process each page */
227 while (SDDS_ReadTable(&SDDS_dataset) > 0) {
228 if ((fromPage > 0 && fromPage > page) || (toPage > 0 && toPage < page)) {
229 continue;
230 }
231
232 rows = SDDS_RowCount(&SDDS_dataset);
233
234 if (style == 1) {
235 if (!SDDS_GetParameter(&SDDS_dataset, "Variable1Name", &xVar)) {
236 fprintf(stderr, "sdds2tiff: problem getting parameter Variable1Name\n");
237 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
238 }
239 if (!SDDS_GetParameter(&SDDS_dataset, "Variable2Name", &yVar)) {
240 fprintf(stderr, "sdds2tiff: problem getting parameter Variable2Name\n");
241 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
242 }
243
244 sprintf(xDimName, "%sDimension", xVar);
245 sprintf(yDimName, "%sDimension", yVar);
246 if (!SDDS_GetParameterAsLong64(&SDDS_dataset, xDimName, &xDim)) {
247 fprintf(stderr, "sdds2tiff: problem getting parameter %s\n", xDimName);
248 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
249 }
250 if (!SDDS_GetParameterAsLong(&SDDS_dataset, yDimName, &yDim)) {
251 fprintf(stderr, "sdds2tiff: problem getting parameter %s\n", yDimName);
252 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
253 }
254
255 fprintf(stderr, "%s %s\n", xVar, yVar);
256 fprintf(stderr, "%" PRId64 " %" PRId32 "\n", xDim, yDim);
257 free(xVar);
258 free(yVar);
259
260 if (xDim * yDim != rows) {
261 fprintf(stderr, "sdds2tiff: %s * %s does not equal the number of rows in the page\n", xDimName, yDimName);
262 return 1;
263 }
264
265 data = malloc(sizeof(*data));
266 data[0] = SDDS_GetColumnInLong(&SDDS_dataset, zColumnName);
267 for (i = 0; i < rows; i++) {
268 if (data[0][i] > maxvalue) {
269 maxvalue = data[0][i];
270 }
271 }
272
273 if (!bit16) {
274 buffer = malloc(rows * sizeof(char));
275 } else {
276 buffer16 = malloc(rows * sizeof(int16_t));
277 }
278 } else if (style == 2) {
279 j = 0;
280 for (i = 0; i < nColumns; i++) {
281 if (strncmp(columnPrefix, columnNames[i], strlen(columnPrefix)) == 0) {
282 data[j] = SDDS_GetColumnInLong(&SDDS_dataset, columnNames[i]);
283 for (k = 0; k < rows; k++) {
284 if (data[j][k] > maxvalue) {
285 maxvalue = data[j][k];
286 }
287 }
288 j++;
289 }
290 }
291
292 if (!bit16) {
293 buffer = malloc(rows * linesFound * sizeof(char));
294 } else {
295 buffer16 = malloc(rows * linesFound * sizeof(uint16_t));
296 }
297
298 xDim = rows;
299 yDim = linesFound;
300 }
301
302 if (maxContrast) {
303 div = maxvalue / maxPossible;
304 } else if (maxvalue <= maxPossibleLong) {
305 div = 1;
306 } else if (maxvalue <= 3 * maxPossibleLong) {
307 div = 3;
308 } else {
309 div = maxvalue / maxPossible;
310 }
311
312 sprintf(outputName, "%s.%04ld", output, index);
313 tif = TIFFOpen(outputName, "w");
314 if (tif) {
315 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, xDim);
316 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, yDim);
317 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bit16 ? 16 : 8);
318 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
319 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, yDim);
320 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
321 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
322 TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
323 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
324 TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
325
326 if (style == 1) {
327 k = 0;
328 for (i = 0; i < xDim; i++) {
329 for (j = 0; j < yDim; j++) {
330 if (!bit16) {
331 buffer[xDim * (yDim - (j + 1)) + i] = (unsigned int)(round(data[0][k] / div));
332 } else {
333 buffer16[xDim * (yDim - (j + 1)) + i] = (uint16_t)(round(data[0][k] / div));
334 }
335 k++;
336 }
337 }
338 TIFFWriteEncodedStrip(tif, 0, bit16 ? (char *)buffer16 : buffer, rows * (bit16 ? 2 : 1));
339 } else if (style == 2) {
340 for (j = 0; j < yDim; j++) {
341 for (i = 0; i < xDim; i++) {
342 if (!bit16) {
343 buffer[j * xDim + i] = (unsigned int)(round(data[(yDim - j) - 1][i] / div));
344 } else {
345 buffer16[j * xDim + i] = (uint16_t)(round(data[(yDim - j) - 1][i] / div));
346 }
347 }
348 }
349 TIFFWriteEncodedStrip(tif, 0, bit16 ? (char *)buffer16 : buffer, xDim * yDim * (bit16 ? 2 : 1));
350 }
351 TIFFClose(tif);
352 }
353
354 if (buffer) {
355 free(buffer);
356 }
357 if (buffer16) {
358 free(buffer16);
359 }
360 if (style == 1) {
361 free(data[0]);
362 free(data);
363 } else if (style == 2) {
364 for (j = 0; j < yDim; j++) {
365 free(data[j]);
366 }
367 }
368
369 index++;
370 }
371
372 if (!SDDS_Terminate(&SDDS_dataset)) {
373 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
374 }
375
376 if (input) {
377 free(input);
378 }
379 if (output) {
380 free(output);
381 }
382 if (outputName) {
383 free(outputName);
384 }
385
386 for (i = 0; i < nColumns; i++) {
387 if (columnNames[i]) {
388 free(columnNames[i]);
389 }
390 }
391
392 if (columnNames) {
393 free(columnNames);
394 }
395
396 if (style == 2 && data) {
397 free(data);
398 }
399
400 free_scanargs(&s_arg, argc);
401 return 0;
402}
int32_t * SDDS_GetParameterAsLong(SDDS_DATASET *SDDS_dataset, char *parameter_name, int32_t *memory)
Retrieves the value of a specified parameter as a 32-bit integer from the current data table of a dat...
int32_t * SDDS_GetColumnInLong(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of 32-bit integers,...
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.
int64_t * SDDS_GetParameterAsLong64(SDDS_DATASET *SDDS_dataset, char *parameter_name, int64_t *memory)
Retrieves the value of a specified parameter as a 64-bit integer from the current data table of an SD...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584

Variable Documentation

◆ option

char* option[N_OPTIONS]
static
Initial value:
= {
"maxcontrast", "frompage", "topage", "columnPrefix", "pipe", "16bit"}

Definition at line 58 of file sdds2tiff.c.

58 {
59 "maxcontrast", "frompage", "topage", "columnPrefix", "pipe", "16bit"};

◆ USAGE

char* USAGE
static
Initial value:
=
"sdds2tiff [-pipe[=input]] <input> <output> \n"
" [-fromPage=<pageNumber>] [-toPage=<pageNumber>]\n"
" [-columnPrefix=<Line>]\n"
" [-maxContrast] [-16bit]\n\n"
" Two styles of input files are accepted:\n"
" 1. A single column SDDS file with Variable1Name and Variable2Name parameters,\n"
" as well as <Variable1Name>Dimension and <Variable2Name>Dimension parameters.\n"
" 2. A file containing multiple columns called Line*.\n"
"\n"
" Each page in the input file will be converted to a separate TIFF image.\n"
" The output files will be named <output>.%04ld\n\n"
" Program by Robert Soliday. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 62 of file sdds2tiff.c.