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 
48 struct GiImage {
49  cpl_image *pixels;
50  cpl_propertylist *properties;
51  cpl_type type;
52 };
53 
54 
64 GiImage *
65 giraffe_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 
94 GiImage *
95 giraffe_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) {
105  giraffe_image_delete(self);
106  self = NULL;
107  }
108  else {
109 
110  self->properties = cpl_propertylist_new();
111 
112  if (self->properties == NULL) {
113  giraffe_image_delete(self);
114  self = NULL;
115  }
116 
117  }
118 
119  }
120 
121  return self;
122 
123 }
124 
125 
138 GiImage *
139 giraffe_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 
180 void
181 giraffe_image_delete(GiImage *self)
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 
217 cpl_image *
218 giraffe_image_get(const GiImage *self)
219 {
220 
221  if (self == NULL) {
222  return NULL;
223  }
224 
225  return self->pixels;
226 
227 }
228 
243 cxint
244 giraffe_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 
281 cpl_propertylist *
282 giraffe_image_get_properties(const GiImage *self)
283 {
284 
285  if (self == NULL) {
286  return NULL;
287  }
288 
289  return self->properties;
290 
291 }
292 
293 
311 cxint
312 giraffe_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 
344 cxint
345 giraffe_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 
450 cxint
451 giraffe_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 
487 cxint
488 giraffe_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 
535 cxint
536 giraffe_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 
569 cxint
570 giraffe_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 
652 cxint
653 giraffe_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 
740 void
741 giraffe_image_print(GiImage *self)
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 
772 cxint
773 giraffe_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 }
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
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
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
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
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
Definition: giimage.c:218
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_new(cpl_type type)
Creates an empty image container.
Definition: giimage.c:65
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
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
GiImage * giraffe_image_duplicate(const GiImage *self)
Creates a copy of an image.
Definition: giimage.c:139
cxint giraffe_add_recipe_info(cpl_propertylist *plist, const GiRecipeInfo *info)
Add recipe specific information to a property list.
Definition: giutils.c:623
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:782

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004