00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include <cxmemory.h>
00033 #include <cxmessages.h>
00034
00035 #include <cpl_type.h>
00036 #include <cpl_image.h>
00037 #include <cpl_propertylist.h>
00038 #include <cpl_error.h>
00039
00040 #include "gialias.h"
00041 #include "giimage.h"
00042
00043
00056 struct GiImage {
00057 cpl_image *pixels;
00058 cpl_propertylist *properties;
00059 cpl_type type;
00060 };
00061
00062
00072 GiImage *
00073 giraffe_image_new(cpl_type type)
00074 {
00075
00076 GiImage *self = cx_calloc(1, sizeof *self);
00077
00078 self->pixels = NULL;
00079 self->properties = NULL;
00080 self->type = type;
00081
00082 return self;
00083
00084 }
00085
00086
00102 GiImage *
00103 giraffe_image_create(cpl_type type, cxint nx, cxint ny)
00104 {
00105
00106 GiImage *self = giraffe_image_new(type);
00107
00108 if (self) {
00109
00110 self->pixels = cpl_image_new(nx, ny, self->type);
00111
00112 if (self->pixels == NULL) {
00113 giraffe_image_delete(self);
00114 self = NULL;
00115 }
00116 else {
00117
00118 self->properties = cpl_propertylist_new();
00119
00120 if (self->properties == NULL) {
00121 giraffe_image_delete(self);
00122 self = NULL;
00123 }
00124
00125 }
00126
00127 }
00128
00129 return self;
00130
00131 }
00132
00133
00146 GiImage *
00147 giraffe_image_duplicate(const GiImage *self)
00148 {
00149
00150 GiImage *clone = NULL;
00151
00152
00153 if (self) {
00154
00155 clone = giraffe_image_new(self->type);
00156
00157 if (clone != NULL) {
00158
00159 if (self->pixels != NULL) {
00160 cx_assert(self->type == cpl_image_get_type(self->pixels));
00161 clone->pixels = cpl_image_duplicate(self->pixels);
00162 }
00163
00164 if (self->properties != NULL) {
00165 clone->properties =
00166 cpl_propertylist_duplicate(self->properties);
00167 }
00168
00169 }
00170
00171 }
00172
00173 return clone;
00174
00175 }
00176
00177
00188 void
00189 giraffe_image_delete(GiImage *self)
00190 {
00191
00192 if (self != NULL) {
00193
00194 if (self->pixels != NULL) {
00195 cpl_image_delete(self->pixels);
00196 self->pixels = NULL;
00197 }
00198
00199 if (self->properties != NULL) {
00200 cpl_propertylist_delete(self->properties);
00201 self->properties = NULL;
00202 }
00203
00204 cx_free(self);
00205 self = NULL;
00206
00207 }
00208
00209 return;
00210
00211 }
00212
00213
00226 cpl_image *
00227 giraffe_image_get(const GiImage *self)
00228 {
00229
00230 if (self == NULL) {
00231 return NULL;
00232 }
00233
00234 return self->pixels;
00235
00236 }
00237
00252 cxint
00253 giraffe_image_set(GiImage *self, cpl_image *image)
00254 {
00255
00256 cx_assert(self != NULL);
00257
00258 if (image == NULL) {
00259 return 1;
00260 }
00261
00262 if (self->type != cpl_image_get_type(image)) {
00263 return 1;
00264 }
00265
00266 if (self->pixels != NULL) {
00267 cpl_image_delete(self->pixels);
00268 self->pixels = NULL;
00269 }
00270
00271 self->pixels = cpl_image_duplicate(image);
00272
00273 return self->pixels ? 0 : 1;
00274
00275 }
00276
00277
00290 cpl_propertylist *
00291 giraffe_image_get_properties(const GiImage *self)
00292 {
00293
00294 if (self == NULL) {
00295 return NULL;
00296 }
00297
00298 return self->properties;
00299
00300 }
00301
00302
00320 cxint
00321 giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
00322 {
00323
00324 if (self == NULL) {
00325 return 1;
00326 }
00327
00328 if (self->properties) {
00329 cpl_propertylist_delete(self->properties);
00330 self->properties = NULL;
00331 }
00332
00333 self->properties = cpl_propertylist_duplicate(properties);
00334
00335 return self->properties ? 0 : 1;
00336
00337 }
00338
00339
00353 cxint
00354 giraffe_image_copy_matrix(GiImage *self, cpl_matrix *matrix)
00355 {
00356
00357 const cxchar *const fctid = "giraffe_image_copy_matrix";
00358
00359 cxint nrow = 0;
00360 cxint ncol = 0;
00361
00362 cxdouble *elements = NULL;
00363
00364
00365 cx_assert(self != NULL);
00366
00367 if (matrix == NULL) {
00368 return 1;
00369 }
00370
00371 nrow = cpl_matrix_get_nrow(matrix);
00372 ncol = cpl_matrix_get_ncol(matrix);
00373 cx_assert(nrow > 0 && ncol > 0);
00374
00375 elements = cpl_matrix_get_data(matrix);
00376 cx_assert(elements != NULL);
00377
00378 if (self->pixels != NULL) {
00379 if (cpl_image_get_size_x(self->pixels) != ncol ||
00380 cpl_image_get_size_y(self->pixels) != nrow) {
00381 cpl_image_delete(self->pixels);
00382 self->pixels = cpl_image_new(ncol, nrow, self->type);
00383 }
00384 }
00385 else {
00386 self->pixels = cpl_image_new(ncol, nrow, self->type);
00387 }
00388
00389 switch (self->type) {
00390 case CPL_TYPE_INT:
00391 {
00392 cxsize i;
00393 cxsize sz = nrow * ncol;
00394
00395 cxint *pixels = cpl_image_get_data_int(self->pixels);
00396
00397
00398 for (i = 0; i < sz; i++) {
00399 pixels[i] = (cxint) elements[i];
00400 }
00401 break;
00402 }
00403
00404 case CPL_TYPE_FLOAT:
00405 {
00406 cxsize i;
00407 cxsize sz = nrow * ncol;
00408
00409 cxfloat *pixels = cpl_image_get_data_float(self->pixels);
00410
00411
00412 for (i = 0; i < sz; i++) {
00413 pixels[i] = (cxfloat) elements[i];
00414 }
00415 break;
00416 }
00417
00418 case CPL_TYPE_DOUBLE:
00419 {
00420 cxsize sz = nrow * ncol * sizeof(cxdouble);
00421
00422 cxptr pixels = cpl_image_get_data(self->pixels);
00423
00424
00425 memcpy(pixels, elements, sz);
00426 break;
00427 }
00428
00429 default:
00430 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00431 return 1;
00432 break;
00433 }
00434
00435 return 0;
00436
00437 }
00438
00439
00459 cxint
00460 giraffe_image_load_pixels(GiImage *self, const cxchar *filename,
00461 cxint position, cxint plane)
00462 {
00463
00464 cx_assert(self != NULL);
00465
00466 if (self->pixels != NULL) {
00467 cpl_image_delete(self->pixels);
00468 self->pixels = NULL;
00469 }
00470
00471 self->pixels = cpl_image_load(filename, self->type, plane, position);
00472
00473 return self->pixels ? 0 : 1;
00474
00475 }
00476
00477
00496 cxint
00497 giraffe_image_load_properties(GiImage *self, const cxchar *filename,
00498 cxint position)
00499 {
00500
00501 cx_assert(self != NULL);
00502
00503 if (self->properties) {
00504 cpl_propertylist_delete(self->properties);
00505 self->properties = NULL;
00506 }
00507
00508 self->properties = cpl_propertylist_load(filename, position);
00509
00510 if (self->properties == NULL) {
00511 return 1;
00512 }
00513
00514 return 0;
00515
00516 }
00517
00518
00539 cxint
00540 giraffe_image_load(GiImage *self, const cxchar *filename, cxint position)
00541 {
00542
00543 cx_assert(self != NULL);
00544
00545 if (giraffe_image_load_pixels(self, filename, position, 0) != 0) {
00546 return 1;
00547 }
00548
00549 if (giraffe_image_load_properties(self, filename, position) != 0) {
00550 return 1;
00551 }
00552
00553 return 0;
00554
00555 }
00556
00557
00573 cxint
00574 giraffe_image_save(GiImage *self, const cxchar *filename)
00575 {
00576
00577 const cxchar *fctid = "giraffe_image_save";
00578
00579
00580 if (filename == NULL) {
00581 return 1;
00582 }
00583
00584 if (self) {
00585
00586 cxint code;
00587 cxint bits_per_pixel;
00588
00589
00590 switch (self->type) {
00591 case CPL_TYPE_INT:
00592 bits_per_pixel = CPL_BPP_32_SIGNED;
00593 break;
00594
00595 case CPL_TYPE_FLOAT:
00596 bits_per_pixel = CPL_BPP_IEEE_FLOAT;
00597 break;
00598
00599 case CPL_TYPE_DOUBLE:
00600
00601
00602
00603 bits_per_pixel = CPL_BPP_IEEE_FLOAT;
00604 break;
00605
00606 default:
00607
00608
00609
00610
00611
00612
00613 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00614 return 1;
00615 break;
00616 }
00617
00618 code = cpl_image_save(self->pixels, filename, bits_per_pixel,
00619 self->properties, CPL_IO_DEFAULT);
00620
00621 if (code != CPL_ERROR_NONE) {
00622 return 1;
00623 }
00624 }
00625
00626 return 0;
00627
00628 }
00629
00630
00656 cxint
00657 giraffe_image_paste(GiImage *self, const GiImage *image, cxint x, cxint y,
00658 cxbool clip)
00659 {
00660
00661 const cxchar *fctid = "giraffe_image_paste";
00662
00663
00664 cx_assert(self != NULL);
00665
00666 if (x < 0 || y < 0) {
00667 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00668 return -1;
00669 }
00670
00671 if (image != NULL) {
00672
00673 cpl_image *_self = giraffe_image_get(self);
00674 cpl_image *_image = giraffe_image_get((GiImage *) image);
00675
00676 cxint i;
00677 cxint nx = cpl_image_get_size_x(_self);
00678 cxint ny = cpl_image_get_size_y(_self);
00679 cxint sx = cpl_image_get_size_x(_image);
00680 cxint sy = cpl_image_get_size_y(_image);
00681 cxint ys = y * nx;
00682
00683 cxptr _spixel = cpl_image_get_data(_self);
00684 cxptr _ipixel = cpl_image_get_data(_image);
00685
00686 cpl_type type = cpl_image_get_type(_self);
00687
00688
00689 if (type != cpl_image_get_type(_image)) {
00690 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
00691 return -4;
00692 }
00693
00694 if ((x + sx) > nx) {
00695 if (clip == FALSE) {
00696 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00697 return -2;
00698 }
00699
00700 sx -= nx - x;
00701 }
00702
00703 if ((y + sy) > ny) {
00704 if (clip == FALSE) {
00705 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00706 return -3;
00707 }
00708
00709 sy -= ny - y;
00710 }
00711
00712 for (i = 0; i < sy; i++) {
00713
00714 cxint bytes = cpl_type_get_sizeof(type);
00715 cxint soffset = (ys + nx * i + x) * bytes;
00716 cxint ioffset = (sx * i) * bytes;
00717 cxint sz = sx * bytes;
00718
00719 memcpy((cxchar*)_spixel + soffset,
00720 (cxchar*)_ipixel + ioffset, sz);
00721
00722 }
00723
00724 }
00725
00726 return 0;
00727
00728 }
00729
00730
00744 void
00745 giraffe_image_print(GiImage *self)
00746 {
00747
00748 if (self) {
00749 cx_print("Resources for Giraffe image at %p:", self);
00750 cx_print(" properties at %p", self->properties);
00751 cx_print(" list size: %" CPL_SIZE_FORMAT "\n",
00752 cpl_propertylist_get_size(self->properties));
00753 cx_print(" pixels at %p:", cpl_image_get_data(self->pixels));
00754 cx_print(" type: %02x", cpl_image_get_type(self->pixels));
00755 cx_print(" x-size: %" CPL_SIZE_FORMAT,
00756 cpl_image_get_size_x(self->pixels));
00757 cx_print(" y-size: %" CPL_SIZE_FORMAT "\n",
00758 cpl_image_get_size_y(self->pixels));
00759 }
00760 else {
00761 cx_print("Invalid input image at %p", self);
00762 }
00763
00764 return;
00765
00766 }
00767
00768
00776 cxint
00777 giraffe_image_add_info(GiImage *image, const GiRecipeInfo *info ,
00778 const cpl_frameset *set)
00779 {
00780
00781 cxint status = 0;
00782
00783 cpl_propertylist *properties = NULL;
00784
00785
00786 if (image == NULL) {
00787 return -1;
00788 }
00789
00790 properties = giraffe_image_get_properties(image);
00791
00792 if (properties == NULL) {
00793 return -2;
00794 }
00795
00796 if (info != NULL) {
00797 status = giraffe_add_recipe_info(properties, info);
00798
00799 if (status != 0) {
00800 return -3;
00801 }
00802
00803 if (set != NULL) {
00804 status = giraffe_add_frameset_info(properties, set,
00805 info->sequence);
00806
00807 if (status != 0) {
00808 return -4;
00809 }
00810 }
00811 }
00812
00813 return 0;
00814
00815 }