SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
tiff2sdds.c File Reference

Detailed Description

Converts a TIFF image to an SDDS file format.

This program reads a TIFF image file and converts its pixel data into the SDDS (Self Describing Data Set) format. It supports extracting specific color channels and arranging the data in a single column or multiple columns based on user options. The input is a TIFF image in RGBA format, and the output is an SDDS binary file.

Usage

tiff2sdds <inputfile> <outputfile>
[-redOnly]
[-greenOnly]
[-blueOnly]
[-singleColumnMode]

Options

Optional Description
-redOnly Extracts the red channel only.
-greenOnly Extracts the green channel only.
-blueOnly Extracts the blue channel only.
-singleColumnMode Outputs pixel data in a single column.

Incompatibilities

  • Only one of -redOnly, -greenOnly, or -blueOnly may be specified.
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

Definition in file tiff2sdds.c.

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

Go to the source code of this file.

Functions

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

Function Documentation

◆ main()

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

Definition at line 78 of file tiff2sdds.c.

78 {
79 SDDS_DATASET SDDS_dataset;
80 SCANNED_ARG *s_arg;
81 TIFF *tif;
82 char *input = NULL, *output = NULL;
83 char **column_names = NULL;
84 int32_t **data;
85 int32_t *indexes = NULL;
86 long rgb[3];
87 long i, j, n = 0, single_column_mode = 0;
88
90
91 rgb[0] = rgb[1] = rgb[2] = 1; /* Enable all color channels by default. */
92
93 argc = scanargs(&s_arg, argc, argv); /* Parse command-line arguments. */
94 if (argc < 3) {
95 fprintf(stderr, "%s", usage);
96 return 1;
97 }
98
99 for (i = 1; i < argc; i++) {
100 if (s_arg[i].arg_type == OPTION) {
101 switch (match_string(s_arg[i].list[0], option, N_OPTIONS, 0)) {
102 case OPT_REDONLY:
103 rgb[0] = 1;
104 rgb[1] = rgb[2] = 0; /* Enable red channel only. */
105 break;
106 case OPT_GREENONLY:
107 rgb[1] = 1;
108 rgb[0] = rgb[2] = 0; /* Enable green channel only. */
109 break;
110 case OPT_BLUEONLY:
111 rgb[2] = 1;
112 rgb[0] = rgb[1] = 0; /* Enable blue channel only. */
113 break;
114 case OPT_SINGLECOLUMNMODE:
115 single_column_mode = 1; /* Enable single column mode. */
116 break;
117 default:
118 fprintf(stderr, "invalid option seen\n%s", usage);
119 return 1;
120 }
121 } else {
122 if (!input)
123 input = s_arg[i].list[0]; /* Assign first non-option argument as input file. */
124 else if (!output)
125 output = s_arg[i].list[0]; /* Assign second non-option argument as output file. */
126 else {
127 fprintf(stderr, "too many filenames\n%s", usage);
128 return 1;
129 }
130 }
131 }
132
133 tif = TIFFOpen(input, "r"); /* Open TIFF file for reading. */
134 if (tif) {
135 uint32_t w, h;
136 size_t npixels;
137 uint32_t *raster;
138 double tmp;
139 int32_t tmp2;
140
141 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); /* Retrieve image width. */
142 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); /* Retrieve image height. */
143 npixels = w * h; /* Calculate total pixels. */
144 raster = (uint32_t *)_TIFFmalloc(npixels * sizeof(uint32_t)); /* Allocate memory for pixel data. */
145 if (raster != NULL) {
146 if (TIFFReadRGBAImage(tif, w, h, raster, 0)) {
147
148 if (!SDDS_InitializeOutput(&SDDS_dataset, SDDS_BINARY, 1, NULL, NULL, output))
149 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
150 if (single_column_mode) {
151 /* Define parameters for single column mode. */
152 if (SDDS_DefineParameter(&SDDS_dataset, "Variable1Name", NULL, NULL, NULL, NULL, SDDS_STRING, "x") < 0) {
153 fprintf(stderr, "Problem defining parameter Variable1Name.\n");
154 return 1;
155 }
156 if (SDDS_DefineParameter(&SDDS_dataset, "Variable2Name", NULL, NULL, NULL, NULL, SDDS_STRING, "y") < 0) {
157 fprintf(stderr, "Problem defining parameter Variable2Name.\n");
158 return 1;
159 }
160 tmp = 1;
161 if (SDDS_DefineParameter1(&SDDS_dataset, "xInterval", NULL, NULL, NULL, NULL, SDDS_DOUBLE, &tmp) < 0) {
162 fprintf(stderr, "Problem defining parameter xInterval.\n");
163 return 1;
164 }
165 if (SDDS_DefineParameter1(&SDDS_dataset, "yInterval", NULL, NULL, NULL, NULL, SDDS_DOUBLE, &tmp) < 0) {
166 fprintf(stderr, "Problem defining parameter yInterval.\n");
167 return 1;
168 }
169 tmp2 = w;
170 if (SDDS_DefineParameter1(&SDDS_dataset, "xDimension", NULL, NULL, NULL, NULL, SDDS_LONG, &tmp2) < 0) {
171 fprintf(stderr, "Problem defining parameter xDimension.\n");
172 return 1;
173 }
174 tmp2 = h;
175 if (SDDS_DefineParameter1(&SDDS_dataset, "yDimension", NULL, NULL, NULL, NULL, SDDS_LONG, &tmp2) < 0) {
176 fprintf(stderr, "Problem defining parameter yDimension.\n");
177 return 1;
178 }
179 tmp = 0;
180 if (SDDS_DefineParameter1(&SDDS_dataset, "xMinimum", NULL, NULL, NULL, NULL, SDDS_DOUBLE, &tmp) < 0) {
181 fprintf(stderr, "Problem defining parameter xMinimum.\n");
182 return 1;
183 }
184 if (SDDS_DefineParameter1(&SDDS_dataset, "yMinimum", NULL, NULL, NULL, NULL, SDDS_DOUBLE, &tmp) < 0) {
185 fprintf(stderr, "Problem defining parameter yMinimum.\n");
186 return 1;
187 }
188 if (SDDS_DefineSimpleColumn(&SDDS_dataset, "z", NULL, SDDS_LONG) < 0) {
189 fprintf(stderr, "Problem defining column z.\n");
190 return 1;
191 }
192 data = malloc(sizeof(*data) * 1);
193 data[0] = malloc(sizeof(*(data[0])) * npixels);
194 } else {
195 /* Define parameters for multi-column mode. */
196 if (SDDS_DefineSimpleColumn(&SDDS_dataset, "Index", NULL, SDDS_LONG) < 0) {
197 fprintf(stderr, "Problem defining column Index.\n");
198 return 1;
199 }
200 indexes = malloc(sizeof(*indexes) * w);
201 column_names = malloc(sizeof(char **) * h);
202 data = malloc(sizeof(*data) * h);
203 for (i = 0; i < h; i++) {
204 column_names[i] = malloc(sizeof(char *) * 15);
205 data[i] = malloc(sizeof(*(data[i])) * w);
206 sprintf(column_names[i], "Line%05ld", i);
207 if (SDDS_DefineSimpleColumn(&SDDS_dataset, column_names[i], NULL, SDDS_LONG) < 0) {
208 fprintf(stderr, "Problem defining column %s.\n", column_names[i]);
209 return 1;
210 }
211 }
212 }
213
214 if (!SDDS_WriteLayout(&SDDS_dataset))
215 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
216 if (single_column_mode) {
217 if (!SDDS_StartPage(&SDDS_dataset, npixels))
218 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
219 for (i = 0; i < h; i++) {
220 for (j = 0; j < w; j++) {
221 /* Process pixel values for single column mode. */
222 data[0][j * h + i] = TIFFGetR(raster[n]) * rgb[0] + TIFFGetG(raster[n]) * rgb[1] + TIFFGetB(raster[n]) * rgb[2];
223 n++;
224 }
225 }
226
227 if (!SDDS_SetColumnFromLongs(&SDDS_dataset, SDDS_SET_BY_NAME, data[0], npixels, "z"))
228 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
229 } else {
230 if (!SDDS_StartPage(&SDDS_dataset, w))
231 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
232 for (i = 0; i < w; i++)
233 indexes[i] = i; /* Initialize index values. */
234 for (i = 0; i < h; i++) {
235 for (j = 0; j < w; j++) {
236 /* Process pixel values for multi-column mode. */
237 data[i][j] = TIFFGetR(raster[n]) * rgb[0] + TIFFGetG(raster[n]) * rgb[1] + TIFFGetB(raster[n]) * rgb[2];
238 n++;
239 }
240 }
241 if (!SDDS_SetColumnFromLongs(&SDDS_dataset, SDDS_SET_BY_NAME, indexes, w, "Index"))
242 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
243 for (i = 0; i < h; i++) {
244 if (!SDDS_SetColumnFromLongs(&SDDS_dataset, SDDS_SET_BY_NAME, data[i], w, column_names[i]))
245 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
246 }
247 }
248
249 if (!SDDS_WritePage(&SDDS_dataset) || !SDDS_Terminate(&SDDS_dataset))
250 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
251
252 if (single_column_mode) {
253 free(data[0]);
254 free(data);
255 } else {
256 for (i = 0; i < h; i++) {
257 free(column_names[i]);
258 free(data[i]);
259 }
260 free(column_names);
261 free(data);
262 }
263 }
264 _TIFFfree(raster); /* Free allocated memory for pixel data. */
265 }
266 TIFFClose(tif); /* Close TIFF file. */
267 }
268 if (indexes)
269 free(indexes); /* Free allocated memory for indexes. */
270 free_scanargs(&s_arg, argc); /* Free scanned arguments. */
271 return 0;
272}
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows,...)
Sets the values for a single data column using long integer numbers.
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_DefineParameter1(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, void *fixed_value)
Defines a data parameter with a fixed numerical value.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
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
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
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
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584