JWS C Library
C language utility library
|
00001 /* 00002 * This work is licensed under a Creative Commons 00003 * Attribution-Noncommercial-Share Alike 3.0 United States License. 00004 * 00005 * http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 00006 * 00007 * You are free: 00008 * 00009 * to Share - to copy, distribute, display, and perform the work 00010 * to Remix - to make derivative works 00011 * 00012 * Under the following conditions: 00013 * 00014 * Attribution. You must attribute the work in the manner specified by the 00015 * author or licensor (but not in any way that suggests that they endorse you 00016 * or your use of the work). 00017 * 00018 * Noncommercial. You may not use this work for commercial purposes. 00019 * 00020 * Share Alike. If you alter, transform, or build upon this work, you may 00021 * distribute the resulting work only under the same or similar license to 00022 * this one. 00023 * 00024 * For any reuse or distribution, you must make clear to others the license 00025 * terms of this work. The best way to do this is by including this header. 00026 * 00027 * Any of the above conditions can be waived if you get permission from the 00028 * copyright holder. 00029 * 00030 * Apart from the remix rights granted under this license, nothing in this 00031 * license impairs or restricts the author's moral rights. 00032 */ 00033 00034 00052 #include <jwsc/config.h> 00053 00054 #include <stdlib.h> 00055 #include <inttypes.h> 00056 #include <math.h> 00057 #include <assert.h> 00058 00059 #include "jwsc/base/error.h" 00060 #include "jwsc/matblock/matblock.h" 00061 #include "jwsc/image/image.h" 00062 #include "jwsc/imgblock/imgblock.h" 00063 00064 #ifdef JWSC_HAVE_DMALLOC 00065 #include <dmalloc.h> 00066 #endif 00067 00068 00085 void create_imgblock_f 00086 ( 00087 Imgblock_f** img_out, 00088 uint32_t num_imgs, 00089 uint32_t num_rows, 00090 uint32_t num_cols 00091 ) 00092 { 00093 uint32_t i; 00094 uint32_t row; 00095 Pixel_f* pxls; 00096 Pixel_f** row_ptrs; 00097 Imgblock_f* img; 00098 00099 assert(num_imgs > 0 && num_rows > 0 && num_cols > 0); 00100 00101 if (*img_out == NULL) 00102 { 00103 assert(*img_out = malloc(sizeof(Imgblock_f))); 00104 (*img_out)->num_imgs = 0; 00105 (*img_out)->num_rows = 0; 00106 (*img_out)->num_cols = 0; 00107 (*img_out)->pxls = NULL; 00108 } 00109 img = *img_out; 00110 00111 if (img->num_imgs != num_imgs || 00112 img->num_rows != num_rows || 00113 img->num_cols != num_cols) 00114 { 00115 pxls = (img->num_imgs > 0 && img->num_rows > 0) ? **(img->pxls) : NULL; 00116 pxls = realloc(pxls, num_imgs*num_rows*num_cols*sizeof(Pixel_f)); 00117 assert(pxls); 00118 00119 row_ptrs = (img->num_imgs > 0) ? *(img->pxls) : NULL; 00120 row_ptrs = realloc(row_ptrs, num_imgs*num_rows*sizeof(Pixel_f*)); 00121 assert(row_ptrs); 00122 00123 img->pxls = realloc(img->pxls, num_imgs*sizeof(Pixel_f**)); 00124 assert(img->pxls); 00125 00126 for (i = 0; i < num_imgs; i++) 00127 { 00128 img->pxls[ i ] = &(row_ptrs[ i*num_rows ]); 00129 00130 for (row = 0; row < num_rows; row++) 00131 { 00132 img->pxls[ i ][ row ] = &(pxls[(row+i*num_rows)*num_cols]); 00133 } 00134 } 00135 img->num_imgs = num_imgs; 00136 img->num_rows = num_rows; 00137 img->num_cols = num_cols; 00138 } 00139 } 00140 00164 void create_init_imgblock_f 00165 ( 00166 Imgblock_f** img_out, 00167 uint32_t num_imgs, 00168 uint32_t num_rows, 00169 uint32_t num_cols, 00170 Pixel_f val 00171 ) 00172 { 00173 uint32_t num_pxls; 00174 uint32_t pxl; 00175 Pixel_f* img_pxls; 00176 00177 create_imgblock_f(img_out, num_imgs, num_rows, num_cols); 00178 img_pxls = **((*img_out)->pxls); 00179 num_pxls = num_imgs*num_rows*num_cols; 00180 00181 for (pxl = 0; pxl < num_pxls; pxl++) 00182 { 00183 img_pxls[ pxl ] = val; 00184 } 00185 } 00186 00208 void create_zero_imgblock_f 00209 ( 00210 Imgblock_f** img_out, 00211 uint32_t num_imgs, 00212 uint32_t num_rows, 00213 uint32_t num_cols 00214 ) 00215 { 00216 Pixel_f p = {0}; 00217 00218 create_init_imgblock_f(img_out, num_imgs, num_rows, num_cols, p); 00219 } 00220 00252 void create_random_imgblock_f 00253 ( 00254 Imgblock_f** img_out, 00255 uint32_t num_imgs, 00256 uint32_t num_rows, 00257 uint32_t num_cols, 00258 Pixel_f min, 00259 Pixel_f max 00260 ) 00261 { 00262 uint32_t num_pxls; 00263 uint32_t pxl; 00264 Pixel_f* img_pxls; 00265 float x; 00266 00267 create_imgblock_f(img_out, num_imgs, num_rows, num_cols); 00268 img_pxls = **((*img_out)->pxls); 00269 num_pxls = num_imgs*num_rows*num_cols; 00270 00271 for (pxl = 0; pxl < num_pxls; pxl++) 00272 { 00273 x = (float)rand() / (float)RAND_MAX; 00274 img_pxls[ pxl ].r = min.r + (max.r - min.r)*x; 00275 x = (float)rand() / (float)RAND_MAX; 00276 img_pxls[ pxl ].g = min.g + (max.g - min.r)*x; 00277 x = (float)rand() / (float)RAND_MAX; 00278 img_pxls[ pxl ].b = min.b + (max.b - min.b)*x; 00279 } 00280 } 00281 00309 Error* create_imgblock_from_matblocks_f 00310 ( 00311 Imgblock_f** img_out, 00312 const Matblock_f* m_r, 00313 const Matblock_f* m_g, 00314 const Matblock_f* m_b 00315 ) 00316 { 00317 uint32_t num_elts; 00318 uint32_t elt; 00319 Pixel_f* img_pxls; 00320 float* m_r_elts; 00321 float* m_g_elts; 00322 float* m_b_elts; 00323 00324 if (m_r->num_mats != m_g->num_mats || m_g->num_mats != m_b->num_mats || 00325 m_r->num_rows != m_g->num_rows || m_g->num_rows != m_b->num_rows || 00326 m_r->num_cols != m_g->num_cols || m_g->num_cols != m_b->num_cols) 00327 { 00328 free_imgblock_f(*img_out); *img_out = NULL; 00329 return JWSC_EARG("Inconsistent imgblock channel sizes"); 00330 } 00331 00332 create_imgblock_f(img_out, m_r->num_mats, m_r->num_rows, m_r->num_cols); 00333 00334 img_pxls = **((*img_out)->pxls); 00335 m_r_elts = **(m_r->elts); 00336 m_g_elts = **(m_g->elts); 00337 m_b_elts = **(m_b->elts); 00338 00339 num_elts = m_r->num_mats*m_r->num_rows*m_r->num_cols; 00340 00341 for (elt = 0; elt < num_elts; elt++) 00342 { 00343 img_pxls[ elt ].r = m_r_elts[ elt ]; 00344 img_pxls[ elt ].g = m_g_elts[ elt ]; 00345 img_pxls[ elt ].b = m_b_elts[ elt ]; 00346 } 00347 00348 return NULL; 00349 } 00350 00369 void create_imgblock_from_matblock_f 00370 ( 00371 Imgblock_f** img_out, 00372 const Matblock_f* m 00373 ) 00374 { 00375 create_imgblock_from_matblocks_f(img_out, m, m, m); 00376 } 00377 00402 void create_matblocks_from_imgblock_f 00403 ( 00404 Matblock_f** m_r_out, 00405 Matblock_f** m_g_out, 00406 Matblock_f** m_b_out, 00407 const Imgblock_f* img 00408 ) 00409 { 00410 uint32_t num_elts; 00411 uint32_t elt; 00412 Pixel_f* img_pxls; 00413 float* m_r_elts; 00414 float* m_g_elts; 00415 float* m_b_elts; 00416 00417 create_matblock_f(m_r_out, img->num_imgs, img->num_rows, img->num_cols); 00418 create_matblock_f(m_g_out, img->num_imgs, img->num_rows, img->num_cols); 00419 create_matblock_f(m_b_out, img->num_imgs, img->num_rows, img->num_cols); 00420 00421 m_r_elts = **((*m_r_out)->elts); 00422 m_g_elts = **((*m_g_out)->elts); 00423 m_b_elts = **((*m_b_out)->elts); 00424 img_pxls = **(img->pxls); 00425 00426 num_elts = img->num_imgs*img->num_rows*img->num_cols; 00427 00428 for (elt = 0; elt < num_elts; elt++) 00429 { 00430 m_r_elts[ elt ] = img_pxls[ elt ].r; 00431 m_g_elts[ elt ] = img_pxls[ elt ].g; 00432 m_b_elts[ elt ] = img_pxls[ elt ].b; 00433 } 00434 } 00435 00460 void create_matblock_from_imgblock_f 00461 ( 00462 Matblock_f** m_out, 00463 const Imgblock_f* img, 00464 float r_weight, 00465 float g_weight, 00466 float b_weight 00467 ) 00468 { 00469 uint32_t num_elts; 00470 uint32_t elt; 00471 float weight_sum; 00472 float* m_elts; 00473 Pixel_f* img_pxls; 00474 00475 assert(r_weight >= 0 && g_weight >= 0 && b_weight >= 0); 00476 00477 if ((weight_sum = r_weight + g_weight + b_weight) != 1.0) 00478 { 00479 r_weight *= 1.0 / weight_sum; 00480 g_weight *= 1.0 / weight_sum; 00481 b_weight *= 1.0 / weight_sum; 00482 } 00483 00484 create_matblock_f(m_out, img->num_imgs, img->num_rows, img->num_cols); 00485 00486 m_elts = **((*m_out)->elts); 00487 img_pxls = **(img->pxls); 00488 00489 num_elts = img->num_imgs*img->num_rows*img->num_cols; 00490 00491 for (elt = 0; elt < num_elts; elt++) 00492 { 00493 m_elts[ elt ] = r_weight*img_pxls[ elt ].r + 00494 g_weight*img_pxls[ elt ].g + 00495 b_weight*img_pxls[ elt ].b; 00496 } 00497 } 00498 00516 void copy_imgblock_f(Imgblock_f** img_out, const Imgblock_f* img_in) 00517 { 00518 uint32_t num_pxls; 00519 uint32_t pxl; 00520 Pixel_f* img_out_pxls; 00521 Pixel_f* img_in_pxls; 00522 00523 create_imgblock_f(img_out, img_in->num_imgs, img_in->num_rows, 00524 img_in->num_cols); 00525 00526 img_out_pxls = **((*img_out)->pxls); 00527 img_in_pxls = **(img_in->pxls); 00528 00529 num_pxls = img_in->num_imgs*img_in->num_rows*img_in->num_cols; 00530 00531 for (pxl = 0; pxl < num_pxls; pxl++ ) 00532 { 00533 img_out_pxls[ pxl ] = img_in_pxls[ pxl ]; 00534 } 00535 } 00536 00565 Error* copy_image_into_imgblock_f 00566 ( 00567 Imgblock_f** ib_out, 00568 const Imgblock_f* ib_in, 00569 const Image_f* i, 00570 Imgblock_image orient, 00571 uint32_t index 00572 ) 00573 { 00574 uint32_t num_imgs, num_rows, num_cols; 00575 uint32_t img, row, col; 00576 uint32_t num_indices; 00577 00578 Imgblock_f* ib; 00579 00580 num_imgs = ib_in->num_imgs; 00581 num_rows = ib_in->num_rows; 00582 num_cols = ib_in->num_cols; 00583 00584 switch (orient) 00585 { 00586 case IMGBLOCK_IMG_IMAGE: 00587 num_indices = ib_in->num_imgs; 00588 if (num_rows != i->num_rows || num_cols != i->num_cols) 00589 { 00590 return JWSC_EARG("Incompatible image and imgblock size"); 00591 } 00592 break; 00593 case IMGBLOCK_ROW_IMAGE: 00594 num_indices = ib_in->num_rows; 00595 if (num_imgs != i->num_rows || num_cols != i->num_cols) 00596 { 00597 return JWSC_EARG("Incompatible image and imgblock size"); 00598 } 00599 break; 00600 default: 00601 num_indices = ib_in->num_cols; 00602 if (num_imgs != i->num_rows || num_rows != i->num_cols) 00603 { 00604 return JWSC_EARG("Incompatible image and imgblock size"); 00605 } 00606 } 00607 if (index >= num_indices) 00608 { 00609 return JWSC_EARG("Invalid index to copy into imgblock"); 00610 } 00611 00612 if (*ib_out != ib_in) 00613 { 00614 copy_imgblock_f(ib_out, ib_in); 00615 } 00616 ib = *ib_out; 00617 00618 switch (orient) 00619 { 00620 case IMGBLOCK_IMG_IMAGE: 00621 for (row = 0; row < num_rows; row++) 00622 { 00623 for (col = 0; col < num_cols; col++) 00624 { 00625 ib->pxls[ index ][ row ][ col ] = i->pxls[ row ][ col ]; 00626 } 00627 } 00628 break; 00629 case IMGBLOCK_ROW_IMAGE: 00630 for (img = 0; img < num_imgs; img++) 00631 { 00632 for (col = 0; col < num_cols; col++) 00633 { 00634 ib->pxls[ img ][ index ][ col ] = i->pxls[ img ][ col ]; 00635 } 00636 } 00637 break; 00638 default: 00639 for (img = 0; img < num_imgs; img++) 00640 { 00641 for (row = 0; row < num_rows; row++) 00642 { 00643 ib->pxls[ img ][ row ][ index ] = i->pxls[ img ][ row ]; 00644 } 00645 } 00646 } 00647 00648 return NULL; 00649 } 00650 00651 00652 00653 00674 Error* copy_image_from_imgblock_f 00675 ( 00676 Image_f** img_out, 00677 const Imgblock_f* img_blk, 00678 Imgblock_image orient, 00679 uint32_t index 00680 ) 00681 { 00682 uint32_t num_imgs, num_rows, num_cols; 00683 uint32_t img, row, col; 00684 uint32_t num_indices; 00685 00686 Image_f* image = NULL; 00687 00688 num_imgs = img_blk->num_imgs; 00689 num_rows = img_blk->num_rows; 00690 num_cols = img_blk->num_cols; 00691 00692 switch (orient) 00693 { 00694 case IMGBLOCK_IMG_IMAGE: 00695 num_indices = img_blk->num_imgs; 00696 break; 00697 case IMGBLOCK_ROW_IMAGE: 00698 num_indices = img_blk->num_rows; 00699 break; 00700 default: 00701 num_indices = img_blk->num_cols; 00702 } 00703 if (index >= num_indices) 00704 { 00705 return JWSC_EARG("Invalid index to copy from imgblock"); 00706 } 00707 00708 switch (orient) 00709 { 00710 case IMGBLOCK_IMG_IMAGE: 00711 create_image_f(img_out, num_rows, num_cols); 00712 image = *img_out; 00713 for (row = 0; row < num_rows; row++) 00714 { 00715 for (col = 0; col < num_cols; col++) 00716 { 00717 image->pxls[ row ][ col ] = 00718 img_blk->pxls[ index ][ row ][ col ]; 00719 } 00720 } 00721 break; 00722 case IMGBLOCK_ROW_IMAGE: 00723 create_image_f(img_out, num_imgs, num_cols); 00724 image = *img_out; 00725 for (img = 0; img < num_imgs; img++) 00726 { 00727 for (col = 0; col < num_cols; col++) 00728 { 00729 image->pxls[ img ][ col ] = 00730 img_blk->pxls[ img ][ index ][ col ]; 00731 } 00732 } 00733 break; 00734 default: 00735 create_image_f(img_out, num_imgs, num_rows); 00736 image = *img_out; 00737 for (img = 0; img < num_imgs; img++) 00738 { 00739 for (row = 0; row < num_rows; row++) 00740 { 00741 image->pxls[ img ][ row ] = 00742 img_blk->pxls[ img ][ row ][ index ]; 00743 } 00744 } 00745 } 00746 00747 return NULL; 00748 } 00749 00763 void free_imgblock_f(Imgblock_f* img) 00764 { 00765 if (img == NULL) return; 00766 00767 free(**(img->pxls)); 00768 free(*(img->pxls)); 00769 free(img->pxls); 00770 free(img); 00771 } 00772