1 // Copyright 2002, 2003, 2005 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * d3/tfile.h: Read and write 3D transformation data files.
26 * This version of ALE reads and writes version 0 3D transformation data files.
34 #define D3_TFILE_VERSION 0
35 #define D3_TFILE_VERSION_MAX 0
37 extern int tfile_input_version
;
38 extern int tfile_output_version
;
41 * Structure to describe a transformation data file to load data from.
50 * Structure to describe a transformation data file to write data to.
61 * Create a new tload_t transformation data file structure, used for
62 * reading data from transformation data files.
65 static inline struct tload_t
*tload_new(const char *filename
) {
66 FILE *file
= fopen (filename
, "r");
67 struct tload_t
*result
= NULL
;
70 fprintf(stderr
, "tload: Error: could not open transformation data file '%s'.", filename
);
74 result
= (struct tload_t
*)
75 malloc(sizeof(struct tload_t
));
76 result
->filename
= filename
;
83 * Load the first transformation from a transformation data file associated with
84 * transformation data file structure T, or return the default transformation
85 * if no transformation is available.
87 * T is a pointer to the tload_t transformation data file structure.
89 * DEFAULT_TRANSFORM is the default transformation result.
91 * IS_DEFAULT is used to signal a non-default transformation result.
94 static inline pt
tload_first(struct tload_t
*t
,
95 pt default_transform
, int *is_default
) {
97 pt result
= default_transform
;
102 * If there is no file, return the default.
109 * Search through the initial part of the file to determine
119 first_character
= fgetc(t
->file
);
121 while (first_character
== ' '
122 || first_character
== 0xa
123 || first_character
== 0xd
124 || first_character
== '\t'
125 || first_character
== '#') {
126 ungetc(first_character
, t
->file
);
128 char *fgets_result
= fgets(line
, 1024, t
->file
);
130 assert(fgets_result
);
132 if (strlen(line
) >= 1023) {
134 "\n3d-trans-load: Error: line too long in input file\n");
138 first_character
= fgetc(t
->file
);
141 if (first_character
!= EOF
)
142 ungetc(first_character
, t
->file
);
144 if (first_character
!= 'W') {
145 fprintf(stderr
, "\n3d-trans-load: First command must be a version number.\n");
150 * Obtain version from version command string.
154 char *fgets_result
= fgets(line
, 1024, t
->file
);
156 assert(fgets_result
);
158 if (strlen(line
) >= 1023) {
160 "\n3d-trans-load: Error: line too long in input file\n");
164 int count
= sscanf(line
, "W %d", &tfile_input_version
);
167 fprintf(stderr
, "Error in 3d transformation "
168 "file version command.\n");
170 } else if (tfile_input_version
> D3_TFILE_VERSION_MAX
) {
171 fprintf(stderr
, "Unsupported 3D transformation "
173 tfile_input_version
);
178 * Read each line of the file until we find a transformation
182 while (!feof(t
->file
)) {
185 if (!fgets(line
, 1024, t
->file
))
188 if (strlen(line
) >= 1023) {
190 "\ntrans-load: Error: line too long in input file\n");
194 const double rtod_multiplier
= 180 / M_PI
;
202 /* Comment or whitespace */
206 /* Default transformation */
213 count
= sscanf(line
, "V %lf", &view_angle
);
216 fprintf(stderr
, "\n3d-trans-load: Error: "
217 "Malformed 'V' command.\n");
221 result
.view_angle(view_angle
/ rtod_multiplier
);
226 /* Euclidean transformation data */
229 double width
, height
;
230 double values
[6] = {0, 0, -1, 0, 0, 0};
233 count
= sscanf(line
, "E %lf%lf%lf%lf%lf%lf%lf%lf",
235 &values
[1], &values
[0], &values
[2],
236 &values
[4], &values
[3], &values
[5]);
239 fprintf(stderr
, "\n3d-trans-load: warning: "
240 "Missing args for 'E'\n");
242 if (width
!= result
.scaled_width()
243 || height
!= result
.scaled_height()) {
244 fprintf(stderr
, "\n3d-trans-load: Error: "
245 "Scaled image width and/or height mismatch.");
248 for (int i
= 3; i
< 6; i
++) {
249 values
[i
] /= rtod_multiplier
;
252 result
.e().set(values
);
259 "\ntrans-load: Error in tload_first: unrecognized command '%s'\n",
266 * EOF reached: return default transformation.
273 * Load the next transformation from a transformation data file associated with
274 * transformation data file structure T, or return the default transformation
275 * if no transformation is available.
277 * T is a pointer to the tload_t transformation data file structure.
279 * IS_P is nonzero if a projective transformation is expected.
281 * DEFAULT_TRANSFORM is the default transformation result.
283 * IS_DEFAULT is used to signal a non-default transformation result.
286 static inline pt
tload_next(struct tload_t
*t
,
287 pt default_transform
, int *is_default
) {
289 pt result
= default_transform
;
294 * Read each line of the file until we find a transformation.
297 while (t
&& !feof(t
->file
)) {
300 if (!fgets(line
, 1024, t
->file
))
303 if (strlen(line
) >= 1023) {
305 "\ntrans-load: warning: line too long in input file\n");
308 const double rtod_multiplier
= 180 / M_PI
;
316 /* Comment or whitespace */
320 /* Default transformation */
327 count
= sscanf(line
, "V %lf", &view_angle
);
330 fprintf(stderr
, "\n3d-trans-load: Error: "
331 "Malformed 'V' command.\n");
335 result
.view_angle(view_angle
/ rtod_multiplier
);
340 /* Euclidean transformation data */
343 double width
, height
;
344 double values
[6] = {0, 0, -1, 0, 0, 0};
347 count
= sscanf(line
, "E %lf%lf%lf%lf%lf%lf%lf%lf",
349 &values
[1], &values
[0], &values
[2],
350 &values
[4], &values
[3], &values
[5]);
353 fprintf(stderr
, "\n3d-trans-load: warning: "
354 "Missing args for 'E'\n");
356 if (width
!= result
.scaled_width()
357 || height
!= result
.scaled_height()) {
358 fprintf(stderr
, "\n3d-trans-load: Error: "
359 "Scaled image width and/or height mismatch.");
362 for (int i
= 3; i
< 6; i
++) {
363 values
[i
] /= rtod_multiplier
;
366 result
.e().set(values
);
373 "\ntrans-load: Error in tload_next: unrecognized command '%s'\n",
383 * Create a new tsave_t transformation data file structure, used for
384 * writing data to transformation data files.
387 static inline struct tsave_t
*tsave_new(const char *filename
) {
388 FILE *file
= fopen (filename
, "w");
389 struct tsave_t
*result
= NULL
;
392 fprintf(stderr
, "tsave: Error: could not open transformation data file '%s'.", filename
);
396 result
= (struct tsave_t
*)
397 malloc(sizeof(struct tsave_t
));
398 result
->filename
= filename
;
400 result
->orig
= "unknown";
401 result
->target
= "unknown";
403 fprintf(file
, "# created by ALE 3D transformation file handler version %d\n",
412 * Save the first transformation to a transformation data file associated with
413 * transformation data file structure T, or do nothing if T is NULL. This
414 * function also establishes the output file version.
416 * OFFSET is the transformation to be saved.
418 * IS_PROJECTIVE indicates whether to write a projective transformation.
422 static inline void tsave_first(struct tsave_t
*t
, pt offset
) {
427 t
->file
= fopen(t
->filename
, "a");
429 tfile_output_version
= 0;
431 fprintf(t
->file
, "# producing 3D transformation file syntax version %d\n", tfile_output_version
);
432 fprintf(t
->file
, "W %d\n", tfile_output_version
);
434 // fprintf(t->file, "# Comment: Target output file is %s\n", t->target);
435 // fprintf(t->file, "# Comment: Original frame is %s\n", t->orig);
437 const double rtod_multiplier
= 180 / M_PI
;
439 fprintf(t
->file
, "V %lf\n", (double) offset
.view_angle() * rtod_multiplier
);
441 fprintf(t
->file
, "E ");
442 fprintf(t
->file
, "%f %f ", (double) offset
.scaled_width(), (double) offset
.scaled_height());
443 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(1));
444 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(0));
445 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(2));
446 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(1) * rtod_multiplier
);
447 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(0) * rtod_multiplier
);
448 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(2) * rtod_multiplier
);
450 fprintf(t
->file
, "\n");
456 * Save the next transformation to a transformation data file associated with
457 * transformation data file structure T, or do nothing if T is NULL.
459 * OFFSET is the transformation to be saved.
461 * IS_PROJECTIVE indicates whether to write a projective transformation.
465 static inline void tsave_next(struct tsave_t
*t
, pt offset
) {
470 t
->file
= fopen(t
->filename
, "a");
472 const double rtod_multiplier
= 180 / M_PI
;
474 fprintf(t
->file
, "V %lf\n", (double) offset
.view_angle() * rtod_multiplier
);
476 fprintf(t
->file
, "E ");
477 fprintf(t
->file
, "%f %f ", (double) offset
.scaled_width(), (double) offset
.scaled_height());
478 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(1));
479 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(0));
480 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(2));
481 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(1) * rtod_multiplier
);
482 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(0) * rtod_multiplier
);
483 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(2) * rtod_multiplier
);
485 fprintf(t
->file
, "\n");
491 * Write information to a transformation file indicating the target output
495 static inline void tsave_target(struct tsave_t
*t
, const char *filename
) {
499 t
->target
= filename
;
501 t
->file
= fopen(t
->filename
, "a");
509 * Write information to a transformation data file indicating the filename
510 * of the original frame (i.e. the first frame in the sequence of input
514 static inline void tsave_orig(struct tsave_t
*t
, const char *filename
) {
522 * Write information to a transformation data file indicating the filename
523 * of a supplemental frame (i.e. a frame in the sequence of input frames
524 * that is not the first frame).
527 static inline void tsave_info(struct tsave_t
*t
, const char *filename
) {
529 t
->file
= fopen(t
->filename
, "a");
531 fprintf(t
->file
, "# Comment: Supplemental frame %s\n", filename
);
538 * Write information to a transformation data file indicating the tonal
539 * registration multiplier.
542 static inline void tsave_trm(struct tsave_t
*t
, ale_real r
, ale_real g
, ale_real b
) {
544 t
->file
= fopen(t
->filename
, "a");
546 fprintf(t
->file
, "# Comment: Exposure [r=%f g=%f b=%f]\n", (double) r
, (double) g
, (double) b
);
553 * Write information to a transformation data file indicating the average
557 static inline void tsave_apm(struct tsave_t
*t
, ale_real r
, ale_real g
, ale_real b
) {
559 t
->file
= fopen(t
->filename
, "a");
561 fprintf(t
->file
, "# Comment: Avg magnitude [r=%f g=%f b=%f]\n", (double) r
, (double) g
, (double) b
);
569 * Destroy a tload_t transformation data file structure.
572 static inline void tload_delete(struct tload_t
*victim
) {
574 fclose(victim
->file
);
579 * Destroy a tsave_t transformation data file structure.
582 static inline void tsave_delete(struct tsave_t
*victim
) {