GIRAFFE Pipeline Reference Manual

giimage.c
1/*
2 * This file is part of the GIRAFFE Pipeline
3 * Copyright (C) 2002-2019 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <cxmemory.h>
25#include <cxmessages.h>
26
27#include <cpl_type.h>
28#include <cpl_image.h>
29#include <cpl_propertylist.h>
30#include <cpl_error.h>
31
32#include "gialias.h"
33#include "giimage.h"
34
35
48struct GiImage {
49 cpl_image *pixels;
50 cpl_propertylist *properties;
51 cpl_type type;
52};
53
54
64GiImage *
65giraffe_image_new(cpl_type type)
66{
67
68 GiImage *self = cx_calloc(1, sizeof *self);
69
70 self->pixels = NULL;
71 self->properties = NULL;
72 self->type = type;
73
74 return self;
75
76}
77
78
94GiImage *
95giraffe_image_create(cpl_type type, cxint nx, cxint ny)
96{
97
98 GiImage *self = giraffe_image_new(type);
99
100 if (self) {
101
102 self->pixels = cpl_image_new(nx, ny, self->type);
103
104 if (self->pixels == NULL) {
106 self = NULL;
107 }
108 else {
109
110 self->properties = cpl_propertylist_new();
111
112 if (self->properties == NULL) {
114 self = NULL;
115 }
116
117 }
118
119 }
120
121 return self;
122
123}
124
125
138GiImage *
139giraffe_image_duplicate(const GiImage *self)
140{
141
142 GiImage *clone = NULL;
143
144
145 if (self) {
146
147 clone = giraffe_image_new(self->type);
148
149 if (clone != NULL) {
150
151 if (self->pixels != NULL) {
152 cx_assert(self->type == cpl_image_get_type(self->pixels));
153 clone->pixels = cpl_image_duplicate(self->pixels);
154 }
155
156 if (self->properties != NULL) {
157 clone->properties =
158 cpl_propertylist_duplicate(self->properties);
159 }
160
161 }
162
163 }
164
165 return clone;
166
167}
168
169
180void
182{
183
184 if (self != NULL) {
185
186 if (self->pixels != NULL) {
187 cpl_image_delete(self->pixels);
188 self->pixels = NULL;
189 }
190
191 if (self->properties != NULL) {
192 cpl_propertylist_delete(self->properties);
193 self->properties = NULL;
194 }
195
196 cx_free(self);
197
198 }
199
200 return;
201
202}
203
204
217cpl_image *
218giraffe_image_get(const GiImage *self)
219{
220
221 if (self == NULL) {
222 return NULL;
223 }
224
225 return self->pixels;
226
227}
228
243cxint
244giraffe_image_set(GiImage *self, cpl_image *image)
245{
246
247 cx_assert(self != NULL);
248
249 if (image == NULL) {
250 return 1;
251 }
252
253 if (self->type != cpl_image_get_type(image)) {
254 return 1;
255 }
256
257 if (self->pixels != NULL) {
258 cpl_image_delete(self->pixels);
259 self->pixels = NULL;
260 }
261
262 self->pixels = cpl_image_duplicate(image);
263
264 return self->pixels ? 0 : 1;
265
266}
267
268
281cpl_propertylist *
283{
284
285 if (self == NULL) {
286 return NULL;
287 }
288
289 return self->properties;
290
291}
292
293
311cxint
312giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
313 {
314
315 if (self == NULL) {
316 return 1;
317 }
318
319 if (self->properties) {
320 cpl_propertylist_delete(self->properties);
321 self->properties = NULL;
322 }
323
324 self->properties = cpl_propertylist_duplicate(properties);
325
326 return self->properties ? 0 : 1;
327
328}
329
330
344cxint
345giraffe_image_copy_matrix(GiImage *self, cpl_matrix *matrix)
346{
347
348 const cxchar *const fctid = "giraffe_image_copy_matrix";
349
350 cxint nrow = 0;
351 cxint ncol = 0;
352
353 cxdouble *elements = NULL;
354
355
356 cx_assert(self != NULL);
357
358 if (matrix == NULL) {
359 return 1;
360 }
361
362 nrow = cpl_matrix_get_nrow(matrix);
363 ncol = cpl_matrix_get_ncol(matrix);
364 cx_assert(nrow > 0 && ncol > 0);
365
366 elements = cpl_matrix_get_data(matrix);
367 cx_assert(elements != NULL);
368
369 if (self->pixels != NULL) {
370 if (cpl_image_get_size_x(self->pixels) != ncol ||
371 cpl_image_get_size_y(self->pixels) != nrow) {
372 cpl_image_delete(self->pixels);
373 self->pixels = cpl_image_new(ncol, nrow, self->type);
374 }
375 }
376 else {
377 self->pixels = cpl_image_new(ncol, nrow, self->type);
378 }
379
380 switch (self->type) {
381 case CPL_TYPE_INT:
382 {
383 cxsize i;
384 cxsize sz = nrow * ncol;
385
386 cxint *pixels = cpl_image_get_data_int(self->pixels);
387
388
389 for (i = 0; i < sz; i++) {
390 pixels[i] = (cxint) elements[i];
391 }
392 break;
393 }
394
395 case CPL_TYPE_FLOAT:
396 {
397 cxsize i;
398 cxsize sz = nrow * ncol;
399
400 cxfloat *pixels = cpl_image_get_data_float(self->pixels);
401
402
403 for (i = 0; i < sz; i++) {
404 pixels[i] = (cxfloat) elements[i];
405 }
406 break;
407 }
408
409 case CPL_TYPE_DOUBLE:
410 {
411 cxsize sz = nrow * ncol * sizeof(cxdouble);
412
413 cxptr pixels = cpl_image_get_data(self->pixels);
414
415
416 memcpy(pixels, elements, sz);
417 break;
418 }
419
420 default:
421 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
422 return 1;
423 break;
424 }
425
426 return 0;
427
428}
429
430
450cxint
451giraffe_image_load_pixels(GiImage *self, const cxchar *filename,
452 cxint position, cxint plane)
453{
454
455 cx_assert(self != NULL);
456
457 if (self->pixels != NULL) {
458 cpl_image_delete(self->pixels);
459 self->pixels = NULL;
460 }
461
462 self->pixels = cpl_image_load(filename, self->type, plane, position);
463
464 return self->pixels ? 0 : 1;
465
466}
467
468
487cxint
488giraffe_image_load_properties(GiImage *self, const cxchar *filename,
489 cxint position)
490{
491
492 cx_assert(self != NULL);
493
494 if (self->properties) {
495 cpl_propertylist_delete(self->properties);
496 self->properties = NULL;
497 }
498
499 /*
500 * Strip comments during load
501 */
502
503 self->properties = cpl_propertylist_load_regexp(filename, position,
504 "^COMMENT$", TRUE);
505
506 if (self->properties == NULL) {
507 return 1;
508 }
509
510 return 0;
511
512}
513
514
535cxint
536giraffe_image_load(GiImage *self, const cxchar *filename, cxint position)
537{
538
539 cx_assert(self != NULL);
540
541 if (giraffe_image_load_pixels(self, filename, position, 0) != 0) {
542 return 1;
543 }
544
545 if (giraffe_image_load_properties(self, filename, position) != 0) {
546 return 1;
547 }
548
549 return 0;
550
551}
552
553
569cxint
570giraffe_image_save(GiImage *self, const cxchar *filename)
571{
572
573 const cxchar *fctid = "giraffe_image_save";
574
575
576 if (filename == NULL) {
577 return 1;
578 }
579
580 if (self) {
581
582 cxint code;
583 cxint bits_per_pixel;
584
585
586 switch (self->type) {
587 case CPL_TYPE_INT:
588 bits_per_pixel = CPL_BPP_32_SIGNED;
589 break;
590
591 case CPL_TYPE_FLOAT:
592 bits_per_pixel = CPL_BPP_IEEE_FLOAT;
593 break;
594
595 case CPL_TYPE_DOUBLE:
596
597 /* CPL_TYPE_DOUBLE images are saved as float */
598
599 bits_per_pixel = CPL_BPP_IEEE_FLOAT;
600 break;
601
602 default:
603
604 /*
605 * If self was properly created using the constructors we
606 * should never reach this point.
607 */
608
609 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
610 return 1;
611 break;
612 }
613
614 code = cpl_image_save(self->pixels, filename, bits_per_pixel,
615 self->properties, CPL_IO_DEFAULT);
616
617 if (code != CPL_ERROR_NONE) {
618 return 1;
619 }
620 }
621
622 return 0;
623
624}
625
626
652cxint
653giraffe_image_paste(GiImage *self, const GiImage *image, cxint x, cxint y,
654 cxbool clip)
655{
656
657 const cxchar *fctid = "giraffe_image_paste";
658
659
660 cx_assert(self != NULL);
661
662 if (x < 0 || y < 0) {
663 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
664 return -1;
665 }
666
667 if (image != NULL) {
668
669 cpl_image *_self = giraffe_image_get(self);
670 cpl_image *_image = giraffe_image_get((GiImage *) image);
671
672 cxint i;
673 cxint nx = cpl_image_get_size_x(_self);
674 cxint ny = cpl_image_get_size_y(_self);
675 cxint sx = cpl_image_get_size_x(_image);
676 cxint sy = cpl_image_get_size_y(_image);
677 cxint ys = y * nx;
678
679 cxptr _spixel = cpl_image_get_data(_self);
680 cxptr _ipixel = cpl_image_get_data(_image);
681
682 cpl_type type = cpl_image_get_type(_self);
683
684
685 if (type != cpl_image_get_type(_image)) {
686 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
687 return -4;
688 }
689
690 if ((x + sx) > nx) {
691 if (clip == FALSE) {
692 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
693 return -2;
694 }
695
696 sx -= nx - x;
697 }
698
699 if ((y + sy) > ny) {
700 if (clip == FALSE) {
701 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
702 return -3;
703 }
704
705 sy -= ny - y;
706 }
707
708 for (i = 0; i < sy; i++) {
709
710 cxint bytes = cpl_type_get_sizeof(type);
711 cxint soffset = (ys + nx * i + x) * bytes;
712 cxint ioffset = (sx * i) * bytes;
713 cxint sz = sx * bytes;
714
715 memcpy((cxchar*)_spixel + soffset,
716 (cxchar*)_ipixel + ioffset, sz);
717
718 }
719
720 }
721
722 return 0;
723
724}
725
726
740void
742{
743
744 if (self) {
745 cx_print("Resources for Giraffe image at %p:", self);
746 cx_print(" properties at %p", self->properties);
747 cx_print(" list size: %" CPL_SIZE_FORMAT "\n",
748 cpl_propertylist_get_size(self->properties));
749 cx_print(" pixels at %p:", cpl_image_get_data(self->pixels));
750 cx_print(" type: %02x", cpl_image_get_type(self->pixels));
751 cx_print(" x-size: %" CPL_SIZE_FORMAT,
752 cpl_image_get_size_x(self->pixels));
753 cx_print(" y-size: %" CPL_SIZE_FORMAT "\n",
754 cpl_image_get_size_y(self->pixels));
755 }
756 else {
757 cx_print("Invalid input image at %p", self);
758 }
759
760 return;
761
762}
763
764
772cxint
773giraffe_image_add_info(GiImage *image, const GiRecipeInfo *info ,
774 const cpl_frameset *set)
775{
776
777 cxint status = 0;
778
779 cpl_propertylist *properties = NULL;
780
781
782 if (image == NULL) {
783 return -1;
784 }
785
786 properties = giraffe_image_get_properties(image);
787
788 if (properties == NULL) {
789 return -2;
790 }
791
792 if (info != NULL) {
793 status = giraffe_add_recipe_info(properties, info);
794
795 if (status != 0) {
796 return -3;
797 }
798
799 if (set != NULL) {
800 status = giraffe_add_frameset_info(properties, set,
801 info->sequence);
802
803 if (status != 0) {
804 return -4;
805 }
806 }
807 }
808
809 return 0;
810
811}
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
Definition: giimage.c:218
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
void giraffe_image_delete(GiImage *self)
Destroys an image.
Definition: giimage.c:181
cxint giraffe_image_load_pixels(GiImage *self, const cxchar *filename, cxint position, cxint plane)
Gets image data from a file.
Definition: giimage.c:451
GiImage * giraffe_image_create(cpl_type type, cxint nx, cxint ny)
Creates an image container of a given type.
Definition: giimage.c:95
GiImage * giraffe_image_duplicate(const GiImage *self)
Creates a copy of an image.
Definition: giimage.c:139
cxint giraffe_image_paste(GiImage *self, const GiImage *image, cxint x, cxint y, cxbool clip)
Paste an image into another at a given position.
Definition: giimage.c:653
cxint giraffe_image_add_info(GiImage *image, const GiRecipeInfo *info, const cpl_frameset *set)
Add additional frame information to an image.
Definition: giimage.c:773
cxint giraffe_image_copy_matrix(GiImage *self, cpl_matrix *matrix)
Copies matrix elements into an image.
Definition: giimage.c:345
cxint giraffe_image_load_properties(GiImage *self, const cxchar *filename, cxint position)
Gets image properties from a file.
Definition: giimage.c:488
cxint giraffe_image_save(GiImage *self, const cxchar *filename)
Write a Giraffe image to a file.
Definition: giimage.c:570
void giraffe_image_print(GiImage *self)
Prints status information about a Giraffe image.
Definition: giimage.c:741
cxint giraffe_image_set(GiImage *self, cpl_image *image)
Sets the image data.
Definition: giimage.c:244
GiImage * giraffe_image_new(cpl_type type)
Creates an empty image container.
Definition: giimage.c:65
cxint giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
Attaches a property list to an image.
Definition: giimage.c:312
cxint giraffe_image_load(GiImage *self, const cxchar *filename, cxint position)
Gets image data and properties from a file.
Definition: giimage.c:536
cxint giraffe_add_recipe_info(cpl_propertylist *plist, const GiRecipeInfo *info)
Add recipe specific information to a property list.
Definition: giutils.c:625
cxint giraffe_add_frameset_info(cpl_propertylist *plist, const cpl_frameset *set, cxint sequence)
Add frameset specific information to a property list.
Definition: giutils.c:784

This file is part of the GIRAFFE Pipeline Reference Manual 2.19.1.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Jul 17 2025 09:27:30 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004