1 /*
2 * options.c: FIASCO options handling
3 *
4 * Written by: Ullrich Hafner
5 *
6 * This file is part of FIASCO (Fractal Image And Sequence COdec)
7 * Copyright (C) 1994-2000 Ullrich Hafner
8 */
9
10 /*
11 * $Date: 2000/10/28 17:39:31 $
12 * $Author: hafner $
13 * $Revision: 5.5 $
14 * $State: Exp $
15 */
16
17 #define _DEFAULT_SOURCE 1 /* New name for SVID & BSD source defines */
18 #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */
19 #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */
20
21 #include "config.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26
27 #include "nstring.h"
28
29 #include "types.h"
30 #include "macros.h"
31 #include "error.h"
32
33 #include "wfa.h"
34 #include "misc.h"
35 #include "bit-io.h"
36 #include "fiasco.h"
37 #include "options.h"
38
39 fiasco_c_options_t *
fiasco_c_options_new(void)40 fiasco_c_options_new (void)
41 /*
42 * FIASCO options constructor.
43 * Allocate memory for the FIASCO coder options structure and
44 * fill in default values.
45 *
46 * Return value:
47 * pointer to the new option structure
48 */
49 {
50 c_options_t *options = calloc (1, sizeof (c_options_t));
51 fiasco_c_options_t *public = calloc (1, sizeof (fiasco_c_options_t));
52
53 if (!options || !public)
54 {
55 set_error (_("Out of memory."));
56 return NULL;
57 }
58 public->private = options;
59 public->delete = fiasco_c_options_delete;
60 public->set_tiling = fiasco_c_options_set_tiling;
61 public->set_frame_pattern = fiasco_c_options_set_frame_pattern;
62 public->set_basisfile = fiasco_c_options_set_basisfile;
63 public->set_chroma_quality = fiasco_c_options_set_chroma_quality;
64 public->set_optimizations = fiasco_c_options_set_optimizations;
65 public->set_video_param = fiasco_c_options_set_video_param;
66 public->set_quantization = fiasco_c_options_set_quantization;
67 public->set_progress_meter = fiasco_c_options_set_progress_meter;
68 public->set_smoothing = fiasco_c_options_set_smoothing;
69 public->set_title = fiasco_c_options_set_title;
70 public->set_comment = fiasco_c_options_set_comment;
71
72 strcpy (options->id, "COFIASCO");
73
74 /*
75 * Set default value of fiasco options
76 */
77 options->basis_name = strdup ("small.fco");
78 options->lc_min_level = 4;
79 options->lc_max_level = 12;
80 options->p_min_level = 8;
81 options->p_max_level = 10;
82 options->images_level = 5;
83 options->max_states = MAXSTATES;
84 options->chroma_max_states = 40;
85 options->max_elements = MAXEDGES;
86 options->tiling_exponent = 4;
87 options->tiling_method = FIASCO_TILING_VARIANCE_DSC;
88 options->id_domain_pool = strdup ("rle");
89 options->id_d_domain_pool = strdup ("rle");
90 options->id_rpf_model = strdup ("adaptive");
91 options->id_d_rpf_model = strdup ("adaptive");
92 options->rpf_mantissa = 3;
93 options->rpf_range = FIASCO_RPF_RANGE_1_50;
94 options->dc_rpf_mantissa = 5;
95 options->dc_rpf_range = FIASCO_RPF_RANGE_1_00;
96 options->d_rpf_mantissa = 3;
97 options->d_rpf_range = FIASCO_RPF_RANGE_1_50;
98 options->d_dc_rpf_mantissa = 5;
99 options->d_dc_rpf_range = FIASCO_RPF_RANGE_1_00;
100 options->chroma_decrease = 2.0;
101 options->prediction = NO;
102 options->delta_domains = YES;
103 options->normal_domains = YES;
104 options->search_range = 16;
105 options->fps = 25;
106 options->pattern = strdup ("IPPPPPPPPP");
107 options->reference_filename = NULL;
108 options->half_pixel_prediction = NO;
109 options->cross_B_search = YES;
110 options->B_as_past_ref = YES;
111 options->check_for_underflow = NO;
112 options->check_for_overflow = NO;
113 options->second_domain_block = NO;
114 options->full_search = NO;
115 options->progress_meter = FIASCO_PROGRESS_NONE;
116 options->smoothing = 70;
117 options->comment = strdup ("");
118 options->title = strdup ("");
119
120 return public;
121 }
122
123 void
fiasco_c_options_delete(fiasco_c_options_t * options)124 fiasco_c_options_delete (fiasco_c_options_t *options)
125 /*
126 * FIASCO options destructor.
127 * Free memory of FIASCO options struct.
128 *
129 * No return value.
130 *
131 * Side effects:
132 * structure 'options' is discarded.
133 */
134 {
135 c_options_t *this = cast_c_options (options);
136
137 if (!this)
138 return;
139
140 Free (this->id_domain_pool);
141 Free (this->id_d_domain_pool);
142 Free (this->id_rpf_model);
143 Free (this->id_d_rpf_model);
144 Free (this->pattern);
145 Free (this->comment);
146 Free (this->title);
147
148 Free (this);
149
150 return;
151 }
152
153 int
fiasco_c_options_set_tiling(fiasco_c_options_t * options,fiasco_tiling_e method,unsigned exponent)154 fiasco_c_options_set_tiling (fiasco_c_options_t *options,
155 fiasco_tiling_e method, unsigned exponent)
156 /*
157 * Set tiling `method' and `exponent'.
158 * See type `fiasco_tiling_e' for a list of valid tiling `methods'.
159 * The image is subdivied into 2^`exponent' tiles
160 *
161 * Return value:
162 * 1 on success
163 * 0 otherwise
164 */
165 {
166 c_options_t *this = (c_options_t *) cast_c_options (options);
167
168 if (!this)
169 {
170 return 0;
171 }
172 switch (method)
173 {
174 case FIASCO_TILING_SPIRAL_ASC:
175 case FIASCO_TILING_SPIRAL_DSC:
176 case FIASCO_TILING_VARIANCE_ASC:
177 case FIASCO_TILING_VARIANCE_DSC:
178 this->tiling_method = method;
179 break;
180 default:
181 set_error (_("Invalid tiling method `%d' specified "
182 "(valid methods are 0, 1, 2, or 3)."), method);
183 return 0;
184 }
185 this->tiling_exponent = exponent;
186
187 return 1;
188 }
189
190 int
fiasco_c_options_set_frame_pattern(fiasco_c_options_t * options,const char * pattern)191 fiasco_c_options_set_frame_pattern (fiasco_c_options_t *options,
192 const char *pattern)
193 /*
194 * Set `pattern' of input frames.
195 * `pattern' has to be a sequence of the following
196 * characters (case insensitive):
197 * 'i' intra frame
198 * 'p' predicted frame
199 * 'b' bidirectional predicted frame
200 * E.g. pattern = 'IBBPBBPBB'
201 *
202 * When coding video frames the prediction type of input frame N is determined
203 * by reading `pattern' [N] (`pattern' is periodically extended).
204 *
205 * Return value:
206 * 1 on success
207 * 0 otherwise
208 */
209 {
210 c_options_t *this = (c_options_t *) cast_c_options (options);
211
212 if (!this)
213 {
214 return 0;
215 }
216 else if (!pattern)
217 {
218 set_error (_("Parameter `%s' not defined (NULL)."), "pattern");
219 return 0;
220 }
221 else if (strlen (pattern) < 1)
222 {
223 set_error (_("Frame type pattern doesn't contain any character."));
224 return 0;
225 }
226 else
227 {
228 const char *str;
229 bool_t parse_error = NO;
230 int c = 0;
231
232 for (str = pattern; *str && !parse_error; str++)
233 switch (*str)
234 {
235 case 'i':
236 case 'I':
237 case 'b':
238 case 'B':
239 case 'p':
240 case 'P':
241 break;
242 default:
243 c = *str;
244 parse_error = YES;
245 }
246
247 if (parse_error)
248 {
249 set_error (_("Frame type pattern contains invalid character `%c' "
250 "(choose I, B or P)."), c);
251 return 0;
252 }
253 else
254 {
255 Free (this->pattern);
256 this->pattern = strdup (pattern);
257
258 return 1;
259 }
260 }
261 }
262
263 int
fiasco_c_options_set_basisfile(fiasco_c_options_t * options,const char * filename)264 fiasco_c_options_set_basisfile (fiasco_c_options_t *options,
265 const char *filename)
266 /*
267 * Set `filename' of FIASCO initial basis.
268 *
269 * Return value:
270 * 1 on success (if the file is readable)
271 * 0 otherwise
272 */
273 {
274 c_options_t *this = (c_options_t *) cast_c_options (options);
275
276 if (!this)
277 {
278 return 0;
279 }
280 else if (!filename)
281 {
282 set_error (_("Parameter `%s' not defined (NULL)."), "filename");
283 return 0;
284 }
285 else
286 {
287 /* Skip this because basis file may be linked with program, not
288 in a separate file. See get_linked_basis(). NETPBM
289 FILE *file = open_file (filename, "FIASCO_DATA", READ_ACCESS);
290 if (file)
291 {
292 fclose (file);
293 return 1;
294 }
295 else
296 {
297 set_error (_("Can't read basis file `%s'.\n%s."), filename,
298 get_system_error ());
299 return 0;
300 }
301 */ return 1;
302 }
303 }
304
305 int
fiasco_c_options_set_chroma_quality(fiasco_c_options_t * options,float quality_factor,unsigned dictionary_size)306 fiasco_c_options_set_chroma_quality (fiasco_c_options_t *options,
307 float quality_factor,
308 unsigned dictionary_size)
309 /*
310 * Set color compression parameters.
311 * When coding chroma channels (Cb and Cr)
312 * - approximation quality is given by `quality_factor' * `Y quality' and
313 * - `dictionary_size' gives the number of dictionary elements.
314 *
315 * If 'quality' <= 0 then the luminancy coding quality is also during
316 * chroma channel coding.
317 *
318 * Return value:
319 * 1 on success
320 * 0 otherwise
321 */
322 {
323 c_options_t *this = (c_options_t *) cast_c_options (options);
324
325 if (!this)
326 {
327 return 0;
328 }
329 else if (!dictionary_size)
330 {
331 set_error (_("Size of chroma compression dictionary has to be "
332 "a positive number."));
333 return 0;
334 }
335 else if (quality_factor <= 0)
336 {
337 set_error (_("Quality of chroma channel compression has to be "
338 "positive value."));
339 return 0;
340 }
341 else
342 {
343 this->chroma_decrease = quality_factor;
344 this->chroma_max_states = dictionary_size;
345
346 return 1;
347 }
348 }
349
350 int
fiasco_c_options_set_optimizations(fiasco_c_options_t * options,unsigned min_block_level,unsigned max_block_level,unsigned max_elements,unsigned dictionary_size,unsigned optimization_level)351 fiasco_c_options_set_optimizations (fiasco_c_options_t *options,
352 unsigned min_block_level,
353 unsigned max_block_level,
354 unsigned max_elements,
355 unsigned dictionary_size,
356 unsigned optimization_level)
357 /*
358 * Set various optimization parameters.
359 * - During compression only image blocks of size
360 * {`min_block_level', ... ,`max_block_level'} are considered.
361 * The smaller this set of blocks is the faster the coder runs
362 * and the worse the image quality will be.
363 * - An individual approximation may use at most `max_elements'
364 * elements of the dictionary which itself contains at most
365 * `dictionary_size' elements. The smaller these values are
366 * the faster the coder runs and the worse the image quality will be.
367 * - `optimization_level' enables some additional low level optimizations.
368 * 0: standard approximation method
369 * 1: significantly increases the approximation quality,
370 * running time is twice as high as with the standard method
371 * 2: hardly increases the approximation quality of method 1,
372 * running time is twice as high as with method 1
373 * (this method just remains for completeness)
374 *
375 * Return value:
376 * 1 on success
377 * 0 otherwise
378 */
379 {
380 c_options_t *this = (c_options_t *) cast_c_options (options);
381
382 if (!this)
383 {
384 return 0;
385 }
386 else if (!dictionary_size)
387 {
388 set_error (_("Size of dictionary has to be a positive number."));
389 return 0;
390 }
391 else if (!max_elements)
392 {
393 set_error (_("At least one dictionary element has to be used "
394 "in an approximation."));
395 return 0;
396 }
397 else if (max_block_level < 4)
398 {
399 set_error (_("Maximum image block size has to be at least level 4."));
400 return 0;
401 }
402 else if (min_block_level < 4)
403 {
404 set_error (_("Minimum image block size has to be at least level 4."));
405 return 0;
406 }
407 else if (max_block_level < min_block_level)
408 {
409 set_error (_("Maximum block size has to be larger or "
410 "equal minimum block size."));
411 return 0;
412 }
413 else
414 {
415 this->lc_min_level = min_block_level;
416 this->lc_max_level = max_block_level;
417 this->max_states = dictionary_size;
418 this->max_elements = max_elements;
419 this->second_domain_block = optimization_level > 0 ? YES : NO;
420 this->check_for_overflow = optimization_level > 1 ? YES : NO;
421 this->check_for_underflow = optimization_level > 1 ? YES : NO;
422 this->full_search = optimization_level > 1 ? YES : NO;
423
424 return 1;
425 }
426 }
427
428 int
fiasco_c_options_set_prediction(fiasco_c_options_t * options,int intra_prediction,unsigned min_block_level,unsigned max_block_level)429 fiasco_c_options_set_prediction (fiasco_c_options_t *options,
430 int intra_prediction,
431 unsigned min_block_level,
432 unsigned max_block_level)
433 /*
434 * Set minimum and maximum size of image block prediction to
435 * `min_block_level' and `max_block_level'.
436 * (For either motion compensated prediction of inter frames
437 * or DC based prediction of intra frames)
438 * Prediction of intra frames is only used if `intra_prediction' != 0.
439 *
440 * Return value:
441 * 1 on success
442 * 0 otherwise
443 */
444 {
445 c_options_t *this = (c_options_t *) cast_c_options (options);
446
447 if (!this)
448 {
449 return 0;
450 }
451 else if (max_block_level < 6)
452 {
453 set_error (_("Maximum prediction block size has to be "
454 "at least level 6"));
455 return 0;
456 }
457 else if (min_block_level < 6)
458 {
459 set_error (_("Minimum prediction block size has to be "
460 "at least level 6"));
461 return 0;
462 }
463 else if (max_block_level < min_block_level)
464 {
465 set_error (_("Maximum prediction block size has to be larger or "
466 "equal minimum block size."));
467 return 0;
468 }
469 else
470 {
471 this->p_min_level = min_block_level;
472 this->p_max_level = max_block_level;
473 this->prediction = intra_prediction;
474
475 return 1;
476 }
477 }
478
479 int
fiasco_c_options_set_video_param(fiasco_c_options_t * options,unsigned frames_per_second,int half_pixel_prediction,int cross_B_search,int B_as_past_ref)480 fiasco_c_options_set_video_param (fiasco_c_options_t *options,
481 unsigned frames_per_second,
482 int half_pixel_prediction,
483 int cross_B_search,
484 int B_as_past_ref)
485 /*
486 * Set various parameters used for video compensation.
487 * 'frames_per_second' defines the frame rate which should be
488 * used when the video is decoded. This value has no effect during coding,
489 * it is just passed to the FIASCO output file.
490 * If 'half_pixel_prediction' is not 0 then half pixel precise
491 * motion compensated prediction is used.
492 * If 'cross_B_search' is not 0 then the fast Cross-B-Search algorithm is
493 * used to determine the motion vectors of interpolated prediction. Otherwise
494 * exhaustive search (in the given search range) is used.
495 * If 'B_as_past_ref' is not 0 then B frames are allowed to be used
496 * for B frame predicion.
497 *
498 * Return value:
499 * 1 on success
500 * 0 otherwise
501 */
502 {
503 c_options_t *this = (c_options_t *) cast_c_options (options);
504
505 if (!this)
506 {
507 return 0;
508 }
509 else
510 {
511 this->fps = frames_per_second;
512 this->half_pixel_prediction = half_pixel_prediction;
513 this->cross_B_search = cross_B_search;
514 this->B_as_past_ref = B_as_past_ref;
515
516 return 1;
517 }
518 }
519
520 int
fiasco_c_options_set_quantization(fiasco_c_options_t * options,unsigned mantissa,fiasco_rpf_range_e range,unsigned dc_mantissa,fiasco_rpf_range_e dc_range)521 fiasco_c_options_set_quantization (fiasco_c_options_t *options,
522 unsigned mantissa,
523 fiasco_rpf_range_e range,
524 unsigned dc_mantissa,
525 fiasco_rpf_range_e dc_range)
526 /*
527 * Set accuracy of coefficients quantization.
528 * DC coefficients (of the constant dictionary vector f(x,y) = 1)
529 * are quantized to values of the interval [-`dc_range', `dc_range'] using
530 * #`dc_mantissa' bits. All other quantized coefficients are quantized in
531 * an analogous way using the parameters `range' and `mantissa'.
532 *
533 * Return value:
534 * 1 on success
535 * 0 otherwise
536 */
537 {
538 c_options_t *this = (c_options_t *) cast_c_options (options);
539
540 if (!this)
541 {
542 return 0;
543 }
544 else if (mantissa < 2 || mantissa > 8 || dc_mantissa < 2 || dc_mantissa > 8)
545 {
546 set_error (_("Number of RPF mantissa bits `%d', `%d' have to be in "
547 "the interval [2,8]."), mantissa, dc_mantissa);
548 return 0;
549 }
550 else
551 {
552 if ((range == FIASCO_RPF_RANGE_0_75
553 || range == FIASCO_RPF_RANGE_1_00
554 || range == FIASCO_RPF_RANGE_1_50
555 || range == FIASCO_RPF_RANGE_2_00)
556 &&
557 (dc_range == FIASCO_RPF_RANGE_0_75
558 || dc_range == FIASCO_RPF_RANGE_1_00
559 || dc_range == FIASCO_RPF_RANGE_1_50
560 || dc_range == FIASCO_RPF_RANGE_2_00))
561 {
562 this->rpf_range = range;
563 this->dc_rpf_range = dc_range;
564 this->rpf_mantissa = mantissa;
565 this->dc_rpf_mantissa = dc_mantissa;
566
567 return 1;
568 }
569 else
570 {
571 set_error (_("Invalid RPF ranges `%d', `%d' specified."),
572 range, dc_range);
573 return 0;
574 }
575 }
576 }
577
578 int
fiasco_c_options_set_progress_meter(fiasco_c_options_t * options,fiasco_progress_e type)579 fiasco_c_options_set_progress_meter (fiasco_c_options_t *options,
580 fiasco_progress_e type)
581 /*
582 * Set type of progress meter.
583 *
584 * Return value:
585 * 1 on success
586 * 0 otherwise
587 */
588 {
589 c_options_t *this = (c_options_t *) cast_c_options (options);
590
591 if (!this)
592 {
593 return 0;
594 }
595 switch (type)
596 {
597 case FIASCO_PROGRESS_BAR:
598 case FIASCO_PROGRESS_PERCENT:
599 case FIASCO_PROGRESS_NONE:
600 this->progress_meter = type;
601 break;
602 default:
603 set_error (_("Invalid progress meter `%d' specified "
604 "(valid values are 0, 1, or 2)."), type);
605 return 0;
606 }
607 return 1;
608 }
609
610 int
fiasco_c_options_set_smoothing(fiasco_c_options_t * options,int smoothing)611 fiasco_c_options_set_smoothing (fiasco_c_options_t *options, int smoothing)
612 /*
613 * Define `smoothing'-percentage along partitioning borders.
614 *
615 * Return value:
616 * 1 on success
617 * 0 otherwise
618 */
619 {
620 c_options_t *this = (c_options_t *) cast_c_options (options);
621
622 if (!this)
623 {
624 return 0;
625 }
626 else if (smoothing < -1 || smoothing > 100)
627 {
628 set_error (_("Smoothing percentage must be in the range [-1, 100]."));
629 return 0;
630 }
631 else
632 {
633 this->smoothing = smoothing;
634 return 1;
635 }
636 }
637
638 int
fiasco_c_options_set_comment(fiasco_c_options_t * options,const char * comment)639 fiasco_c_options_set_comment (fiasco_c_options_t *options, const char *comment)
640 /*
641 * Define `comment' of FIASCO stream.
642 *
643 * Return value:
644 * 1 on success
645 * 0 otherwise
646 */
647 {
648 c_options_t *this = (c_options_t *) cast_c_options (options);
649
650 if (!this)
651 {
652 return 0;
653 }
654 else if (!comment)
655 {
656 set_error (_("Parameter `%s' not defined (NULL)."), "title");
657 return 0;
658 }
659 else
660 {
661 this->comment = strdup (comment);
662 return 1;
663 }
664 }
665
666 int
fiasco_c_options_set_title(fiasco_c_options_t * options,const char * title)667 fiasco_c_options_set_title (fiasco_c_options_t *options, const char *title)
668 /*
669 * Define `title' of FIASCO stream.
670 *
671 * Return value:
672 * 1 on success
673 * 0 otherwise
674 */
675 {
676 c_options_t *this = (c_options_t *) cast_c_options (options);
677
678 if (!this)
679 {
680 return 0;
681 }
682 else if (!title)
683 {
684 set_error (_("Parameter `%s' not defined (NULL)."), "title");
685 return 0;
686 }
687 else
688 {
689 this->title = strdup (title);
690 return 1;
691 }
692 }
693
694 c_options_t *
cast_c_options(fiasco_c_options_t * options)695 cast_c_options (fiasco_c_options_t *options)
696 /*
697 * Cast generic pointer `options' to type c_options_t.
698 * Check whether `options' is a valid object of type c_options_t.
699 *
700 * Return value:
701 * pointer to options struct on success
702 * NULL otherwise
703 */
704 {
705 c_options_t *this = (c_options_t *) options->private;
706 if (this)
707 {
708 if (!streq (this->id, "COFIASCO"))
709 {
710 set_error (_("Parameter `options' doesn't match required type."));
711 return NULL;
712 }
713 }
714 else
715 {
716 set_error (_("Parameter `%s' not defined (NULL)."), "options");
717 }
718
719 return this;
720 }
721
722 /**************************************************************************
723 ***************************************************************************
724 DECODER
725 ***************************************************************************
726 **************************************************************************/
727
728 fiasco_d_options_t *
fiasco_d_options_new(void)729 fiasco_d_options_new (void)
730 /*
731 * FIASCO options constructor.
732 * Allocate memory for the FIASCO coder options structure and
733 * fill in default values.
734 *
735 * Return value:
736 * pointer to the new option structure
737 */
738 {
739 d_options_t *options = calloc (1, sizeof (d_options_t));
740 fiasco_d_options_t *public = calloc (1, sizeof (fiasco_d_options_t));
741
742 if (!options || !public)
743 {
744 set_error (_("Out of memory."));
745 return NULL;
746 }
747 public->private = options;
748 public->delete = fiasco_d_options_delete;
749 public->set_smoothing = fiasco_d_options_set_smoothing;
750 public->set_magnification = fiasco_d_options_set_magnification;
751 public->set_4_2_0_format = fiasco_d_options_set_4_2_0_format;
752
753 strcpy (options->id, "DOFIASCO");
754
755 /*
756 * Set default value of fiasco decoder options
757 */
758 options->smoothing = 70;
759 options->magnification = 0;
760 options->image_format = FORMAT_4_4_4;
761
762 return public;
763 }
764
765 void
fiasco_d_options_delete(fiasco_d_options_t * options)766 fiasco_d_options_delete (fiasco_d_options_t *options)
767 /*
768 * FIASCO options destructor.
769 * Free memory of FIASCO options struct.
770 *
771 * No return value.
772 *
773 * Side effects:
774 * structure 'options' is discarded.
775 */
776 {
777 d_options_t *this = cast_d_options (options);
778
779 if (!this)
780 return;
781
782 Free (this);
783
784 return;
785 }
786
787 int
fiasco_d_options_set_smoothing(fiasco_d_options_t * options,int smoothing)788 fiasco_d_options_set_smoothing (fiasco_d_options_t *options, int smoothing)
789 /*
790 * Define `smoothing'-percentage along partitioning borders.
791 *
792 * Return value:
793 * 1 on success
794 * 0 otherwise
795 */
796 {
797 d_options_t *this = (d_options_t *) cast_d_options (options);
798
799 if (!this)
800 {
801 return 0;
802 }
803 else if (smoothing < -1 || smoothing > 100)
804 {
805 set_error (_("Smoothing percentage must be in the range [-1, 100]."));
806 return 0;
807 }
808 else
809 {
810 this->smoothing = smoothing;
811 return 1;
812 }
813 }
814
815 int
fiasco_d_options_set_magnification(fiasco_d_options_t * options,int level)816 fiasco_d_options_set_magnification (fiasco_d_options_t *options, int level)
817 /*
818 * Set magnification-'level' of decoded image.
819 * 0: width x height of original image
820 * 1: (2 * width) x (2 * height) of original image
821 * -1: (width / 2 ) x (height / 2) of original image
822 * etc.
823 *
824 * Return value:
825 * 1 on success
826 * 0 otherwise
827 */
828 {
829 d_options_t *this = (d_options_t *) cast_d_options (options);
830
831 if (!this)
832 {
833 return 0;
834 }
835 else
836 {
837 this->magnification = level;
838 return 1;
839 }
840 }
841
842 int
fiasco_d_options_set_4_2_0_format(fiasco_d_options_t * options,int format)843 fiasco_d_options_set_4_2_0_format (fiasco_d_options_t *options, int format)
844 /*
845 * Set image format to 4:2:0 or 4:4:4.
846 *
847 * Return value:
848 * 1 on success
849 * 0 otherwise
850 */
851 {
852 d_options_t *this = (d_options_t *) cast_d_options (options);
853
854 if (!this)
855 {
856 return 0;
857 }
858 else
859 {
860 this->image_format = format ? FORMAT_4_2_0 : FORMAT_4_4_4;
861 return 1;
862 }
863 }
864
865 d_options_t *
cast_d_options(fiasco_d_options_t * options)866 cast_d_options (fiasco_d_options_t *options)
867 /*
868 * Cast generic pointer `options' to type d_options_t.
869 * Check whether `options' is a valid object of type d_options_t.
870 *
871 * Return value:
872 * pointer to options struct on success
873 * NULL otherwise
874 */
875 {
876 d_options_t *this = (d_options_t *) options->private;
877
878 if (this)
879 {
880 if (!streq (this->id, "DOFIASCO"))
881 {
882 set_error (_("Parameter `options' doesn't match required type."));
883 return NULL;
884 }
885 }
886 else
887 {
888 set_error (_("Parameter `%s' not defined (NULL)."), "options");
889 }
890
891 return this;
892 }
893
894
895