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
00206 }
00207
00208 return;
00209
00210 }
00211
00212
00225 cpl_image *
00226 giraffe_image_get(const GiImage *self)
00227 {
00228
00229 if (self == NULL) {
00230 return NULL;
00231 }
00232
00233 return self->pixels;
00234
00235 }
00236
00251 cxint
00252 giraffe_image_set(GiImage *self, cpl_image *image)
00253 {
00254
00255 cx_assert(self != NULL);
00256
00257 if (image == NULL) {
00258 return 1;
00259 }
00260
00261 if (self->type != cpl_image_get_type(image)) {
00262 return 1;
00263 }
00264
00265 if (self->pixels != NULL) {
00266 cpl_image_delete(self->pixels);
00267 self->pixels = NULL;
00268 }
00269
00270 self->pixels = cpl_image_duplicate(image);
00271
00272 return self->pixels ? 0 : 1;
00273
00274 }
00275
00276
00289 cpl_propertylist *
00290 giraffe_image_get_properties(const GiImage *self)
00291 {
00292
00293 if (self == NULL) {
00294 return NULL;
00295 }
00296
00297 return self->properties;
00298
00299 }
00300
00301
00319 cxint
00320 giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
00321 {
00322
00323 if (self == NULL) {
00324 return 1;
00325 }
00326
00327 if (self->properties) {
00328 cpl_propertylist_delete(self->properties);
00329 self->properties = NULL;
00330 }
00331
00332 self->properties = cpl_propertylist_duplicate(properties);
00333
00334 return self->properties ? 0 : 1;
00335
00336 }
00337
00338
00352 cxint
00353 giraffe_image_copy_matrix(GiImage *self, cpl_matrix *matrix)
00354 {
00355
00356 const cxchar *const fctid = "giraffe_image_copy_matrix";
00357
00358 cxint nrow = 0;
00359 cxint ncol = 0;
00360
00361 cxdouble *elements = NULL;
00362
00363
00364 cx_assert(self != NULL);
00365
00366 if (matrix == NULL) {
00367 return 1;
00368 }
00369
00370 nrow = cpl_matrix_get_nrow(matrix);
00371 ncol = cpl_matrix_get_ncol(matrix);
00372 cx_assert(nrow > 0 && ncol > 0);
00373
00374 elements = cpl_matrix_get_data(matrix);
00375 cx_assert(elements != NULL);
00376
00377 if (self->pixels != NULL) {
00378 if (cpl_image_get_size_x(self->pixels) != ncol ||
00379 cpl_image_get_size_y(self->pixels) != nrow) {
00380 cpl_image_delete(self->pixels);
00381 self->pixels = cpl_image_new(ncol, nrow, self->type);
00382 }
00383 }
00384 else {
00385 self->pixels = cpl_image_new(ncol, nrow, self->type);
00386 }
00387
00388 switch (self->type) {
00389 case CPL_TYPE_INT:
00390 {
00391 cxsize i;
00392 cxsize sz = nrow * ncol;
00393
00394 cxint *pixels = cpl_image_get_data_int(self->pixels);
00395
00396
00397 for (i = 0; i < sz; i++) {
00398 pixels[i] = (cxint) elements[i];
00399 }
00400 break;
00401 }
00402
00403 case CPL_TYPE_FLOAT:
00404 {
00405 cxsize i;
00406 cxsize sz = nrow * ncol;
00407
00408 cxfloat *pixels = cpl_image_get_data_float(self->pixels);
00409
00410
00411 for (i = 0; i < sz; i++) {
00412 pixels[i] = (cxfloat) elements[i];
00413 }
00414 break;
00415 }
00416
00417 case CPL_TYPE_DOUBLE:
00418 {
00419 cxsize sz = nrow * ncol * sizeof(cxdouble);
00420
00421 cxptr pixels = cpl_image_get_data(self->pixels);
00422
00423
00424 memcpy(pixels, elements, sz);
00425 break;
00426 }
00427
00428 default:
00429 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00430 return 1;
00431 break;
00432 }
00433
00434 return 0;
00435
00436 }
00437
00438
00458 cxint
00459 giraffe_image_load_pixels(GiImage *self, const cxchar *filename,
00460 cxint position, cxint plane)
00461 {
00462
00463 cx_assert(self != NULL);
00464
00465 if (self->pixels != NULL) {
00466 cpl_image_delete(self->pixels);
00467 self->pixels = NULL;
00468 }
00469
00470 self->pixels = cpl_image_load(filename, self->type, plane, position);
00471
00472 return self->pixels ? 0 : 1;
00473
00474 }
00475
00476
00495 cxint
00496 giraffe_image_load_properties(GiImage *self, const cxchar *filename,
00497 cxint position)
00498 {
00499
00500 cx_assert(self != NULL);
00501
00502 if (self->properties) {
00503 cpl_propertylist_delete(self->properties);
00504 self->properties = NULL;
00505 }
00506
00507 self->properties = cpl_propertylist_load(filename, position);
00508
00509 if (self->properties == NULL) {
00510 return 1;
00511 }
00512
00513 return 0;
00514
00515 }
00516
00517
00538 cxint
00539 giraffe_image_load(GiImage *self, const cxchar *filename, cxint position)
00540 {
00541
00542 cx_assert(self != NULL);
00543
00544 if (giraffe_image_load_pixels(self, filename, position, 0) != 0) {
00545 return 1;
00546 }
00547
00548 if (giraffe_image_load_properties(self, filename, position) != 0) {
00549 return 1;
00550 }
00551
00552 return 0;
00553
00554 }
00555
00556
00572 cxint
00573 giraffe_image_save(GiImage *self, const cxchar *filename)
00574 {
00575
00576 const cxchar *fctid = "giraffe_image_save";
00577
00578
00579 if (filename == NULL) {
00580 return 1;
00581 }
00582
00583 if (self) {
00584
00585 cxint code;
00586 cxint bits_per_pixel;
00587
00588
00589 switch (self->type) {
00590 case CPL_TYPE_INT:
00591 bits_per_pixel = CPL_BPP_32_SIGNED;
00592 break;
00593
00594 case CPL_TYPE_FLOAT:
00595 bits_per_pixel = CPL_BPP_IEEE_FLOAT;
00596 break;
00597
00598 case CPL_TYPE_DOUBLE:
00599
00600
00601
00602 bits_per_pixel = CPL_BPP_IEEE_FLOAT;
00603 break;
00604
00605 default:
00606
00607
00608
00609
00610
00611
00612 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00613 return 1;
00614 break;
00615 }
00616
00617 code = cpl_image_save(self->pixels, filename, bits_per_pixel,
00618 self->properties, CPL_IO_DEFAULT);
00619
00620 if (code != CPL_ERROR_NONE) {
00621 return 1;
00622 }
00623 }
00624
00625 return 0;
00626
00627 }
00628
00629
00655 cxint
00656 giraffe_image_paste(GiImage *self, const GiImage *image, cxint x, cxint y,
00657 cxbool clip)
00658 {
00659
00660 const cxchar *fctid = "giraffe_image_paste";
00661
00662
00663 cx_assert(self != NULL);
00664
00665 if (x < 0 || y < 0) {
00666 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00667 return -1;
00668 }
00669
00670 if (image != NULL) {
00671
00672 cpl_image *_self = giraffe_image_get(self);
00673 cpl_image *_image = giraffe_image_get((GiImage *) image);
00674
00675 cxint i;
00676 cxint nx = cpl_image_get_size_x(_self);
00677 cxint ny = cpl_image_get_size_y(_self);
00678 cxint sx = cpl_image_get_size_x(_image);
00679 cxint sy = cpl_image_get_size_y(_image);
00680 cxint ys = y * nx;
00681
00682 cxptr _spixel = cpl_image_get_data(_self);
00683 cxptr _ipixel = cpl_image_get_data(_image);
00684
00685 cpl_type type = cpl_image_get_type(_self);
00686
00687
00688 if (type != cpl_image_get_type(_image)) {
00689 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
00690 return -4;
00691 }
00692
00693 if ((x + sx) > nx) {
00694 if (clip == FALSE) {
00695 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00696 return -2;
00697 }
00698
00699 sx -= nx - x;
00700 }
00701
00702 if ((y + sy) > ny) {
00703 if (clip == FALSE) {
00704 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00705 return -3;
00706 }
00707
00708 sy -= ny - y;
00709 }
00710
00711 for (i = 0; i < sy; i++) {
00712
00713 cxint bytes = cpl_type_get_sizeof(type);
00714 cxint soffset = (ys + nx * i + x) * bytes;
00715 cxint ioffset = (sx * i) * bytes;
00716 cxint sz = sx * bytes;
00717
00718 memcpy((cxchar*)_spixel + soffset,
00719 (cxchar*)_ipixel + ioffset, sz);
00720
00721 }
00722
00723 }
00724
00725 return 0;
00726
00727 }
00728
00729
00743 void
00744 giraffe_image_print(GiImage *self)
00745 {
00746
00747 if (self) {
00748 cx_print("Resources for Giraffe image at %p:", self);
00749 cx_print(" properties at %p", self->properties);
00750 cx_print(" list size: %" CPL_SIZE_FORMAT "\n",
00751 cpl_propertylist_get_size(self->properties));
00752 cx_print(" pixels at %p:", cpl_image_get_data(self->pixels));
00753 cx_print(" type: %02x", cpl_image_get_type(self->pixels));
00754 cx_print(" x-size: %" CPL_SIZE_FORMAT,
00755 cpl_image_get_size_x(self->pixels));
00756 cx_print(" y-size: %" CPL_SIZE_FORMAT "\n",
00757 cpl_image_get_size_y(self->pixels));
00758 }
00759 else {
00760 cx_print("Invalid input image at %p", self);
00761 }
00762
00763 return;
00764
00765 }
00766
00767
00775 cxint
00776 giraffe_image_add_info(GiImage *image, const GiRecipeInfo *info ,
00777 const cpl_frameset *set)
00778 {
00779
00780 cxint status = 0;
00781
00782 cpl_propertylist *properties = NULL;
00783
00784
00785 if (image == NULL) {
00786 return -1;
00787 }
00788
00789 properties = giraffe_image_get_properties(image);
00790
00791 if (properties == NULL) {
00792 return -2;
00793 }
00794
00795 if (info != NULL) {
00796 status = giraffe_add_recipe_info(properties, info);
00797
00798 if (status != 0) {
00799 return -3;
00800 }
00801
00802 if (set != NULL) {
00803 status = giraffe_add_frameset_info(properties, set,
00804 info->sequence);
00805
00806 if (status != 0) {
00807 return -4;
00808 }
00809 }
00810 }
00811
00812 return 0;
00813
00814 }