JWS C Library
C language utility library
imgblock.c
Go to the documentation of this file.
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