1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
|
/*
* This file is part of the HDRL
* Copyright (C) 2013,2014 European Southern Observatory
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*-----------------------------------------------------------------------------
Includes
-----------------------------------------------------------------------------*/
#include "hdrl_image.h"
#include "hdrl_imagelist.h"
#include "hdrl_imagelist_defs.h"
#include "hdrl_imagelist_view.h"
#include "hdrl_iter.h"
#include <cpl.h>
#include <assert.h>
#include <string.h>
/*-----------------------------------------------------------------------------
Defines
-----------------------------------------------------------------------------*/
#define HDRL_MSG "Imagelist with %d image(s)\n"
#define HDRL_IMSG "Image nb %d of %d in imagelist\n"
/*-----------------------------------------------------------------------------
Static Prototypes
-----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/**
* @addtogroup hdrl_imagelist
* @{
*/
/*----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
Function codes
-----------------------------------------------------------------------------*/
/* ---------------------------------------------------------------------------*/
/**
* @internal
* @brief resize buffer to set size
* @param h imagelist to update
* @param size capacity the buffer should have, minimum 128
*
* only changes the buffer size, not the number of contained images
*/
/* ---------------------------------------------------------------------------*/
static void hdrl_imagelist_set_capacity(hdrl_imagelist * h, cpl_size size)
{
h->capacity = CX_MAX(h->ni, CX_MAX(128, size));
h->images = cpl_realloc(h->images, h->capacity * sizeof(h->images[0]));
}
/*----------------------------------------------------------------------------*/
/**
@brief Create an empty imagelist
@return 1 newly allocated hdrl_imagelist
@see hdrl_imagelist_set()
The returned hdrl_imagelist must be deallocated using hdrl_imagelist_delete()
*/
/*----------------------------------------------------------------------------*/
hdrl_imagelist * hdrl_imagelist_new(void)
{
hdrl_imagelist * h = cpl_calloc(1, sizeof(hdrl_imagelist));
hdrl_imagelist_set_capacity(h, 128);
return h;
}
/*----------------------------------------------------------------------------*/
/**
@brief Create an hdrl_imagelist out of 2 cpl_imagelist
@param imlist the list of image
@param errlist the list of errors
@return The new hdrl_imagelist
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
*/
/*----------------------------------------------------------------------------*/
hdrl_imagelist * hdrl_imagelist_create(
cpl_imagelist * imlist,
cpl_imagelist * errlist)
{
hdrl_imagelist * himlist ;
cpl_image * error ;
/* Check Entries */
cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
if (errlist) {
cpl_ensure(cpl_imagelist_get_size(imlist) ==
cpl_imagelist_get_size(errlist), CPL_ERROR_ILLEGAL_INPUT, NULL);
}
/* Create the new HDRL image list */
himlist = hdrl_imagelist_new() ;
/* Loop on the input image list */
for (cpl_size i = 0; i < cpl_imagelist_get_size(imlist); i++) {
/* Get the error image */
hdrl_image * tmp ;
if (errlist) {
error = cpl_imagelist_get(errlist, i) ;
} else {
error = NULL ;
}
/* Create the HDRL image */
tmp = hdrl_image_create(cpl_imagelist_get_const(imlist, i), error) ;
/* Fill the HDRL image list */
hdrl_imagelist_set(himlist, tmp, i);
}
return himlist ;
}
/*----------------------------------------------------------------------------*/
/**
@brief Get the number of images in the imagelist
@param himlist the list of images
@return The number of images or -1 on error
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
*/
/*----------------------------------------------------------------------------*/
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist * himlist)
{
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
assert( himlist->ni >= 0 );
return himlist->ni;
}
/*----------------------------------------------------------------------------*/
/**
@brief Get number of colums of images in the imagelist
@param himlist the list of images
@return The number of columns of images or -1 on error
assumes the imagelist is uniform (cpl_imagelist_is_uniform)
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_ILLEGAL_INPUT if the list is empty
*/
/*----------------------------------------------------------------------------*/
cpl_size hdrl_imagelist_get_size_x(const hdrl_imagelist * himlist)
{
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
cpl_ensure(himlist->ni > 0, CPL_ERROR_ILLEGAL_INPUT, -1);
return hdrl_image_get_size_x(hdrl_imagelist_get_const(himlist, 0));
}
/*----------------------------------------------------------------------------*/
/**
@brief Get number of rows of images in the imagelist
@param himlist the list of images
@return The number of rows of images or -1 on error
assumes the imagelist is uniform (cpl_imagelist_is_uniform)
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_ILLEGAL_INPUT if the list is empty
*/
/*----------------------------------------------------------------------------*/
cpl_size hdrl_imagelist_get_size_y(const hdrl_imagelist * himlist)
{
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
cpl_ensure(himlist->ni > 0, CPL_ERROR_ILLEGAL_INPUT, -1);
return hdrl_image_get_size_y(hdrl_imagelist_get_const(himlist, 0));
}
/*----------------------------------------------------------------------------*/
/**
@brief Get an image from a list of images
@param himlist the image list
@param inum the image id (from 0 to number of images-1)
@return A pointer to the image or NULL in error case.
The returned pointer refers to already allocated data.
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_ACCESS_OUT_OF_RANGE if inum is bigger thant the list size
- CPL_ERROR_ILLEGAL_INPUT if inum is negative
*/
/*----------------------------------------------------------------------------*/
hdrl_image * hdrl_imagelist_get(
const hdrl_imagelist * himlist,
cpl_size inum)
{
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
cpl_ensure(inum >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
cpl_ensure(inum < himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
return himlist->images[inum];
}
/*----------------------------------------------------------------------------*/
/**
@brief Get an image from a list of images
@param himlist the image list
@param inum the image id (from 0 to number of images-1)
@return A pointer to the image or NULL in error case.
@see hdrl_imagelist_get
*/
/*----------------------------------------------------------------------------*/
const hdrl_image * hdrl_imagelist_get_const(
const hdrl_imagelist * himlist,
cpl_size inum)
{
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
cpl_ensure(inum >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
cpl_ensure(inum < himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
return himlist->images[inum];
}
/*----------------------------------------------------------------------------*/
/**
@brief Insert an image into an imagelist
@param himlist The imagelist
@param himg The image to insert
@param pos The list position (from 0 to number of images)
@return CPL_ERROR_NONE or the relevant cpl_error_code on error
It is allowed to specify the position equal to the number of images in the
list. This will increment the size of the imagelist.
No action occurs if an image is inserted more than once into the same
position. It is allowed to insert the same image into two different
positions in a list.
The image is inserted at the position pos in the image list. If the image
already there is only present in that one location in the list, then the
image is deallocated.
It is not allowed to insert images of different size into a list.
The added image is owned by the imagelist object, which deallocates it
hdrl_imagelist_delete is called. Other option is to use
hdrl_imagelist_unset to recover ownership of the image, in which case
the hdrl_imagelist object is not longer responsible for deallocating it.
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_ILLEGAL_INPUT if pos is negative
- CPL_ERROR_TYPE_MISMATCH if himg and himlist are of different types
- CPL_ERROR_INCOMPATIBLE_INPUT if himg and himlist have different sizes
- CPL_ERROR_ACCESS_OUT_OF_RANGE if pos is bigger than the number of
images in himlist
*/
/*----------------------------------------------------------------------------*/
cpl_error_code hdrl_imagelist_set(
hdrl_imagelist * himlist,
hdrl_image * himg,
cpl_size pos)
{
cpl_ensure_code(himlist, CPL_ERROR_NULL_INPUT);
cpl_ensure_code(himg, CPL_ERROR_NULL_INPUT);
cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
cpl_ensure_code(pos <= himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE);
/* Do nothing if the image is already there */
if (pos < himlist->ni && himg == himlist->images[pos])
return CPL_ERROR_NONE;
if (pos > 0 || himlist->ni > 1) {
/* Require images to have the same size and type */
cpl_ensure_code(hdrl_image_get_size_x(himg) ==
hdrl_image_get_size_x(himlist->images[0]),
CPL_ERROR_INCOMPATIBLE_INPUT);
cpl_ensure_code(hdrl_image_get_size_y(himg) ==
hdrl_image_get_size_y(himlist->images[0]),
CPL_ERROR_INCOMPATIBLE_INPUT);
// TODO : type of hdrl_image ??
//cpl_ensure_code(hdrl_image_get_type(himg) ==
// hdrl_image_get_type(himlist->images[0]),
// CPL_ERROR_TYPE_MISMATCH);
}
if (pos == himlist->ni) {
/* double buffer if required */
if (pos >= himlist->capacity) {
hdrl_imagelist_set_capacity(himlist, 2 * pos);
}
himlist->ni++;
} else {
/* Check if the image at the position to be overwritten
is present in only one position */
int i;
for (i = 0; i < himlist->ni; i++) {
if (i != pos && himlist->images[i] == himlist->images[pos]) break;
}
if (i == himlist->ni) {
/* The image at the position to be overwritten
is present in only one position, so delete it */
hdrl_image_delete(himlist->images[pos]);
}
}
himlist->images[pos] = himg;
return CPL_ERROR_NONE;
}
/*----------------------------------------------------------------------------*/
/**
@brief Remove an image from an imagelist
@param himlist The imagelist
@param pos The list position (from 0 to number of images-1)
@return The pointer to the removed image or NULL in error case
The specified image is not deallocated, it is simply removed from the
list. The pointer to the image is returned to let the user decide to
deallocate it or not.
Eventually, the image will have to be deallocated with hdrl_image_delete().
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_ILLEGAL_INPUT if pos is negative
- CPL_ERROR_ACCESS_OUT_OF_RANGE if pos is bigger than the number of
images in himlist
*/
/*----------------------------------------------------------------------------*/
hdrl_image * hdrl_imagelist_unset(
hdrl_imagelist * himlist,
cpl_size pos)
{
hdrl_image * out;
cpl_size i;
cpl_ensure(himlist, CPL_ERROR_NULL_INPUT, NULL);
cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
cpl_ensure(pos < himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
/* Get pointer to image to be removed */
out = himlist->images[pos];
/* Move the following images one position towards zero */
for (i=pos + 1; i < himlist->ni; i++) {
himlist->images[i-1] = himlist->images[i];
}
/* Decrement of the size */
himlist->ni--;
/* shrink the buffer if its significantly too large */
if (himlist->ni < himlist->capacity / 2) {
hdrl_imagelist_set_capacity(himlist, himlist->ni / 2);
}
return out;
}
/*----------------------------------------------------------------------------*/
/**
@brief Free all memory used by a hdrl_imagelist object including the images
@param himlist The image list or NULL
@return Nothing
@see hdrl_imagelist_empty(), hdrl_imagelist_unwrap()
*/
/*----------------------------------------------------------------------------*/
void hdrl_imagelist_delete(hdrl_imagelist * himlist)
{
if (himlist != NULL) {
hdrl_imagelist_empty(himlist);
hdrl_imagelist_unwrap(himlist);
}
}
/*----------------------------------------------------------------------------*/
/**
@brief Empty an imagelist and deallocate all its images
@param himlist The image list or NULL
@return Nothing
@see hdrl_imagelist_empty(), hdrl_imagelist_delete()
@note If @em himlist is @c NULL nothing is done and no error is set.
After the call the image list can be populated again. It must eventually
be deallocated with a call to hdrl_imagelist_delete().
*/
/*----------------------------------------------------------------------------*/
void hdrl_imagelist_empty(hdrl_imagelist * himlist)
{
if (himlist != NULL) {
while (himlist->ni > 0) { /* An iteration may unset more than 1 image */
cpl_size i = himlist->ni - 1;
hdrl_image *del = hdrl_imagelist_unset(himlist, i);
/* If this image was inserted more than once into the list,
the other insertions must be unset without a delete. */
while (--i >= 0) {
if (himlist->images[i] == del) {
/* This image was inserted more than once in the list */
del = hdrl_imagelist_unset(himlist, i);
}
}
hdrl_image_delete(del);
}
}
}
/*----------------------------------------------------------------------------*/
/**
@brief Duplicate an image list
@param himlist Source image list.
@return 1 newly allocated image list, or NULL on error.
Copy an image list into a new image list object.
The returned image list must be deallocated using hdrl_imagelist_delete().
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
*/
/*----------------------------------------------------------------------------*/
hdrl_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist * himlist)
{
hdrl_imagelist * out;
cpl_size i;
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
/* Create the new imagelist */
out = hdrl_imagelist_new();
/* Duplicate the images */
for (i=0; i<himlist->ni; i++) {
hdrl_imagelist_set(out, hdrl_image_duplicate(himlist->images[i]), i);
}
return out;
}
/*----------------------------------------------------------------------------*/
/**
@brief Determine if an imagelist contains images of equal size and type
@param himlist The imagelist to check
@return Zero if ok, positive if not consistent and negative on error.
The function returns 1 if the list is empty.
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
*/
/*----------------------------------------------------------------------------*/
int hdrl_imagelist_is_consistent(const hdrl_imagelist * himlist)
{
cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
if (himlist->ni == 0) return 1;
/* Check the images */
// TODO
return 0;
}
/*----------------------------------------------------------------------------*/
/**
@brief Dump structural information of images in an imagelist
@param himlist Imagelist to dump
@param stream Output stream, accepts @c stdout or @c stderr
@return CPL_ERROR_NONE or the relevant cpl_error_code on error
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_FILE_IO if a write operation fails
*/
/*----------------------------------------------------------------------------*/
cpl_error_code hdrl_imagelist_dump_structure(
const hdrl_imagelist * himlist,
FILE * stream)
{
const int msgmin = (int)strlen(HDRL_MSG) - 5;
int i;
cpl_ensure_code(himlist != NULL, CPL_ERROR_NULL_INPUT);
cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
cpl_ensure_code( fprintf(stream, HDRL_MSG, (int)himlist->ni) >= msgmin,
CPL_ERROR_FILE_IO );
for (i = 0; i < himlist -> ni; i++) {
const hdrl_image * image = hdrl_imagelist_get_const(himlist, i);
const int imsgmin = (int)strlen(HDRL_IMSG) - 5;
cpl_ensure_code( fprintf(stream, HDRL_IMSG, i, (int)himlist->ni) >= imsgmin,
CPL_ERROR_FILE_IO );
cpl_ensure_code( !hdrl_image_dump_structure(image, stream),
cpl_error_get_code() );
}
return CPL_ERROR_NONE;
}
/*----------------------------------------------------------------------------*/
/**
@brief Dump pixel values of images in a imagelist
@param himlist Imagelist to dump
@param llx Specifies the window position
@param lly Specifies the window position
@param urx Specifies the window position
@param ury Specifies the window position
@param stream Output stream, accepts @c stdout or @c stderr
@return CPL_ERROR_NONE or the relevant cpl_error_code on error
Possible cpl_error_code set in this function:
- CPL_ERROR_NULL_INPUT if an input pointer is NULL
- CPL_ERROR_FILE_IO if a write operation fails
- CPL_ERROR_ACCESS_OUT_OF_RANGE if the defined window is not in the image
- CPL_ERROR_ILLEGAL_INPUT if the window definition is wrong (e.g llx > urx)
*/
/*----------------------------------------------------------------------------*/
cpl_error_code hdrl_imagelist_dump_window(
const hdrl_imagelist * himlist,
cpl_size llx,
cpl_size lly,
cpl_size urx,
cpl_size ury,
FILE * stream)
{
cpl_size i;
cpl_ensure_code(himlist != NULL, CPL_ERROR_NULL_INPUT);
cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
for (i = 0; i < himlist -> ni; i++) {
const hdrl_image * image = hdrl_imagelist_get_const(himlist, i);
const int imsgmin = (int)strlen(HDRL_IMSG) - 5;
cpl_ensure_code( fprintf(stream, HDRL_IMSG, (int)i,
(int)himlist->ni) >= imsgmin, CPL_ERROR_FILE_IO );
cpl_ensure_code( !hdrl_image_dump_window(image, llx, lly, urx, ury,
stream),
cpl_error_get_code() );
}
return CPL_ERROR_NONE;
}
/*----------------------------------------------------------------------------*/
/**
@internal
@brief Free memory used by a hdrl_imagelist object, except the images
@param himlist The image list or NULL
@return Nothing
@see hdrl_imagelist_empty()
@note The caller must have pointers to all images in the list and is
reponsible for their deallocation. If @em himlist is @c NULL nothing is
done and no error is set.
*/
/*----------------------------------------------------------------------------*/
void hdrl_imagelist_unwrap(hdrl_imagelist * himlist)
{
if (himlist != NULL) {
cpl_free(himlist->images);
cpl_free(himlist);
}
return;
}
typedef struct {
const hdrl_imagelist * hlist;
cpl_size ny;
cpl_size prev_pos;
cpl_size pos;
cpl_size nrows;
cpl_size overlap;
hdrl_imagelist * last_view;
} hdrl_imagelist_row_slices_iter;
static void * hdrl_imagelist_row_slices_next(hdrl_iter * it)
{
hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
if (s->pos > s->ny) {
return NULL;
}
cpl_size lower = CX_MAX(s->pos - s->overlap, 1);
cpl_size upper = CX_MIN(s->pos + s->nrows + s->overlap - 1, s->ny);
/* const iterator means you cannot modify the data but the created views
* can have a NULL bpm which can be faster e.g. when calling
* cpl_image_new_from_accepted on the view */
/* TODO could set memory readonly? */
hdrl_imagelist * view;
CPL_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
if (hdrl_iter_check(it, HDRL_ITER_CONST)) {
view = (hdrl_imagelist*)
hdrl_imagelist_const_row_view((hdrl_imagelist*)s->hlist,
lower, upper);
}
else {
view = hdrl_imagelist_row_view((hdrl_imagelist*)s->hlist,
lower, upper);
}
CPL_DIAG_PRAGMA_POP;
s->prev_pos = s->pos;
s->pos = CX_MIN(s->pos + s->nrows - 1, s->ny) + 1;
if (hdrl_iter_check(it, HDRL_ITER_OWNS_DATA)) {
hdrl_imagelist_delete(s->last_view);
s->last_view = view;
}
return view;
}
hdrl_il_rowsliceiter_data
hdrl_imagelist_iter_row_slices_get_data(const hdrl_iter * it)
{
hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
if (s->prev_pos == 1) {
return (hdrl_il_rowsliceiter_data){1., CX_MIN(s->nrows, s->ny)};
}
else {
return (hdrl_il_rowsliceiter_data){s->overlap + 1, s->overlap + s->pos - s->prev_pos};
}
}
static cpl_size hdrl_imagelist_row_slices_length(hdrl_iter * it)
{
hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
return s->ny / s->nrows + ((s->ny % s->nrows) != 0);
}
static void hdrl_imagelist_iter_delete(void * it)
{
if (!it)
return;
hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
hdrl_imagelist_delete(s->last_view);
cpl_free(s);
}
/* TODO, add offset and stride for parallel processing? or imagelist_split? */
hdrl_iter * hdrl_imagelist_get_iter_row_slices(const hdrl_imagelist * hlist,
cpl_size nrows,
cpl_size overlap,
hdrl_iter_flags flags)
{
cpl_ensure(hlist, CPL_ERROR_NULL_INPUT, NULL);
/* 0 accepted for now, could mean choosen by function */
cpl_ensure(nrows >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
cpl_ensure(hdrl_imagelist_get_size(hlist) > 0,
CPL_ERROR_ILLEGAL_INPUT, NULL);
hdrl_imagelist_row_slices_iter * state = cpl_malloc(sizeof(*state));
state->hlist = hlist;
state->ny = hdrl_imagelist_get_size_y(hlist);
state->prev_pos = 1;
state->pos = 1;
state->overlap = CX_MAX(overlap, 0);
state->nrows = CX_MAX(nrows, 1);
state->last_view = NULL;
return hdrl_iter_init(hdrl_imagelist_row_slices_next, NULL,
hdrl_imagelist_row_slices_length,
hdrl_imagelist_iter_delete,
HDRL_ITER_INPUT | HDRL_ITER_IMAGELIST | flags,
state);
}
/**@}*/
|