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 2 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 fgets(line
, 1024, t
->file
);
129 if (strlen(line
) >= 1023) {
131 "\n3d-trans-load: Error: line too long in input file\n");
135 first_character
= fgetc(t
->file
);
138 if (first_character
!= EOF
)
139 ungetc(first_character
, t
->file
);
141 if (first_character
!= 'W') {
142 fprintf(stderr
, "\n3d-trans-load: First command must be a version number.\n");
147 * Obtain version from version command string.
151 fgets(line
, 1024, t
->file
);
152 if (strlen(line
) >= 1023) {
154 "\n3d-trans-load: Error: line too long in input file\n");
158 int count
= sscanf(line
, "W %d", &tfile_input_version
);
161 fprintf(stderr
, "Error in 3d transformation "
162 "file version command.\n");
164 } else if (tfile_input_version
> D3_TFILE_VERSION_MAX
) {
165 fprintf(stderr
, "Unsupported 3D transformation "
167 tfile_input_version
);
172 * Read each line of the file until we find a transformation
176 while (!feof(t
->file
)) {
179 fgets(line
, 1024, t
->file
);
184 if (strlen(line
) >= 1023) {
186 "\ntrans-load: Error: line too long in input file\n");
190 const double rtod_multiplier
= 180 / M_PI
;
198 /* Comment or whitespace */
202 /* Default transformation */
209 count
= sscanf(line
, "V %lf", &view_angle
);
212 fprintf(stderr
, "\n3d-trans-load: Error: "
213 "Malformed 'V' command.\n");
217 result
.view_angle(view_angle
/ rtod_multiplier
);
222 /* Euclidean transformation data */
225 double width
, height
;
226 double values
[6] = {0, 0, -1, 0, 0, 0};
229 count
= sscanf(line
, "E %lf%lf%lf%lf%lf%lf%lf%lf",
231 &values
[1], &values
[0], &values
[2],
232 &values
[4], &values
[3], &values
[5]);
235 fprintf(stderr
, "\n3d-trans-load: warning: "
236 "Missing args for 'E'\n");
238 if (width
!= result
.scaled_width()
239 || height
!= result
.scaled_height()) {
240 fprintf(stderr
, "\n3d-trans-load: Error: "
241 "Scaled image width and/or height mismatch.");
244 for (int i
= 3; i
< 6; i
++) {
245 values
[i
] /= rtod_multiplier
;
248 result
.e().set(values
);
255 "\ntrans-load: Error in tload_first: unrecognized command '%s'\n",
262 * EOF reached: return default transformation.
269 * Load the next transformation from a transformation data file associated with
270 * transformation data file structure T, or return the default transformation
271 * if no transformation is available.
273 * T is a pointer to the tload_t transformation data file structure.
275 * IS_P is nonzero if a projective transformation is expected.
277 * DEFAULT_TRANSFORM is the default transformation result.
279 * IS_DEFAULT is used to signal a non-default transformation result.
282 static inline pt
tload_next(struct tload_t
*t
,
283 pt default_transform
, int *is_default
) {
285 pt result
= default_transform
;
290 * Read each line of the file until we find a transformation.
293 while (t
&& !feof(t
->file
)) {
296 fgets(line
, 1024, t
->file
);
301 if (strlen(line
) >= 1023) {
303 "\ntrans-load: warning: line too long in input file\n");
306 const double rtod_multiplier
= 180 / M_PI
;
314 /* Comment or whitespace */
318 /* Default transformation */
325 count
= sscanf(line
, "V %lf", &view_angle
);
328 fprintf(stderr
, "\n3d-trans-load: Error: "
329 "Malformed 'V' command.\n");
333 result
.view_angle(view_angle
/ rtod_multiplier
);
338 /* Euclidean transformation data */
341 double width
, height
;
342 double values
[6] = {0, 0, -1, 0, 0, 0};
345 count
= sscanf(line
, "E %lf%lf%lf%lf%lf%lf%lf%lf",
347 &values
[1], &values
[0], &values
[2],
348 &values
[4], &values
[3], &values
[5]);
351 fprintf(stderr
, "\n3d-trans-load: warning: "
352 "Missing args for 'E'\n");
354 if (width
!= result
.scaled_width()
355 || height
!= result
.scaled_height()) {
356 fprintf(stderr
, "\n3d-trans-load: Error: "
357 "Scaled image width and/or height mismatch.");
360 for (int i
= 3; i
< 6; i
++) {
361 values
[i
] /= rtod_multiplier
;
364 result
.e().set(values
);
371 "\ntrans-load: Error in tload_next: unrecognized command '%s'\n",
381 * Create a new tsave_t transformation data file structure, used for
382 * writing data to transformation data files.
385 static inline struct tsave_t
*tsave_new(const char *filename
) {
386 FILE *file
= fopen (filename
, "w");
387 struct tsave_t
*result
= NULL
;
390 fprintf(stderr
, "tsave: Error: could not open transformation data file '%s'.", filename
);
394 result
= (struct tsave_t
*)
395 malloc(sizeof(struct tsave_t
));
396 result
->filename
= filename
;
398 result
->orig
= "unknown";
399 result
->target
= "unknown";
401 fprintf(file
, "# created by ALE 3D transformation file handler version %d\n",
410 * Save the first transformation to a transformation data file associated with
411 * transformation data file structure T, or do nothing if T is NULL. This
412 * function also establishes the output file version.
414 * OFFSET is the transformation to be saved.
416 * IS_PROJECTIVE indicates whether to write a projective transformation.
420 static inline void tsave_first(struct tsave_t
*t
, pt offset
) {
425 t
->file
= fopen(t
->filename
, "a");
427 tfile_output_version
= 0;
429 fprintf(t
->file
, "# producing 3D transformation file syntax version %d\n", tfile_output_version
);
430 fprintf(t
->file
, "W %d\n", tfile_output_version
);
432 // fprintf(t->file, "# Comment: Target output file is %s\n", t->target);
433 // fprintf(t->file, "# Comment: Original frame is %s\n", t->orig);
435 const double rtod_multiplier
= 180 / M_PI
;
437 fprintf(t
->file
, "V %lf\n", offset
.view_angle() * rtod_multiplier
);
439 fprintf(t
->file
, "E ");
440 fprintf(t
->file
, "%f %f ", (double) offset
.scaled_width(), (double) offset
.scaled_height());
441 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(1));
442 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(0));
443 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(2));
444 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(1) * rtod_multiplier
);
445 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(0) * rtod_multiplier
);
446 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(2) * rtod_multiplier
);
448 fprintf(t
->file
, "\n");
454 * Save the next transformation to a transformation data file associated with
455 * transformation data file structure T, or do nothing if T is NULL.
457 * OFFSET is the transformation to be saved.
459 * IS_PROJECTIVE indicates whether to write a projective transformation.
463 static inline void tsave_next(struct tsave_t
*t
, pt offset
) {
468 t
->file
= fopen(t
->filename
, "a");
470 const double rtod_multiplier
= 180 / M_PI
;
472 fprintf(t
->file
, "V %lf\n", offset
.view_angle() * rtod_multiplier
);
474 fprintf(t
->file
, "E ");
475 fprintf(t
->file
, "%f %f ", (double) offset
.scaled_width(), (double) offset
.scaled_height());
476 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(1));
477 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(0));
478 fprintf(t
->file
, "%f ", (double) offset
.e().get_translation(2));
479 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(1) * rtod_multiplier
);
480 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(0) * rtod_multiplier
);
481 fprintf(t
->file
, "%f ", (double) offset
.e().get_rotation(2) * rtod_multiplier
);
483 fprintf(t
->file
, "\n");
489 * Write information to a transformation file indicating the target output
493 static inline void tsave_target(struct tsave_t
*t
, const char *filename
) {
497 t
->target
= filename
;
499 t
->file
= fopen(t
->filename
, "a");
507 * Write information to a transformation data file indicating the filename
508 * of the original frame (i.e. the first frame in the sequence of input
512 static inline void tsave_orig(struct tsave_t
*t
, const char *filename
) {
520 * Write information to a transformation data file indicating the filename
521 * of a supplemental frame (i.e. a frame in the sequence of input frames
522 * that is not the first frame).
525 static inline void tsave_info(struct tsave_t
*t
, const char *filename
) {
527 t
->file
= fopen(t
->filename
, "a");
529 fprintf(t
->file
, "# Comment: Supplemental frame %s\n", filename
);
536 * Write information to a transformation data file indicating the tonal
537 * registration multiplier.
540 static inline void tsave_trm(struct tsave_t
*t
, ale_real r
, ale_real g
, ale_real b
) {
542 t
->file
= fopen(t
->filename
, "a");
544 fprintf(t
->file
, "# Comment: Exposure [r=%f g=%f b=%f]\n", r
, g
, b
);
551 * Write information to a transformation data file indicating the average
555 static inline void tsave_apm(struct tsave_t
*t
, ale_real r
, ale_real g
, ale_real b
) {
557 t
->file
= fopen(t
->filename
, "a");
559 fprintf(t
->file
, "# Comment: Avg magnitude [r=%f g=%f b=%f]\n", r
, g
, b
);
567 * Destroy a tload_t transformation data file structure.
570 static inline void tload_delete(struct tload_t
*victim
) {
572 fclose(victim
->file
);
577 * Destroy a tsave_t transformation data file structure.
580 static inline void tsave_delete(struct tsave_t
*victim
) {