JWS C Library
C language utility library
image.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/matrix/matrix.h"
00061 #include "jwsc/image/image.h"
00062 
00063 #ifdef JWSC_HAVE_DMALLOC
00064 #include <dmalloc.h>
00065 #endif
00066 
00067 
00083 void create_image_f
00084 (
00085     Image_f** img_out, 
00086     uint32_t  num_rows, 
00087     uint32_t  num_cols
00088 )
00089 {
00090     uint32_t row;
00091     Pixel_f* pxls;
00092     Image_f* img;
00093 
00094     assert(num_rows > 0 && num_cols > 0);
00095 
00096     if (*img_out == NULL)
00097     {
00098         assert(*img_out = malloc(sizeof(Image_f)));
00099         (*img_out)->num_rows = 0;
00100         (*img_out)->num_cols = 0;
00101         (*img_out)->pxls     = NULL;
00102     }
00103     img = *img_out;
00104 
00105     if (img->num_rows != num_rows || img->num_cols != num_cols)
00106     {
00107         pxls = (img->pxls != NULL) ? *(img->pxls) : NULL;
00108         pxls = realloc(pxls, num_rows*num_cols*sizeof(Pixel_f));
00109         assert(pxls);
00110 
00111         img->pxls = realloc(img->pxls, num_rows*sizeof(Pixel_f*));
00112         assert(img->pxls);
00113 
00114         for (row = 0; row < num_rows; row++)
00115         {
00116             img->pxls[ row ] = &(pxls[ row*num_cols ]);
00117         }
00118         img->num_rows = num_rows;
00119         img->num_cols = num_cols;
00120     }
00121 }
00122 
00144 void create_init_image_f
00145 (
00146     Image_f** img_out, 
00147     uint32_t  num_rows, 
00148     uint32_t  num_cols,
00149     Pixel_f   val
00150 )
00151 {
00152     uint32_t num_pxls;
00153     uint32_t pxl;
00154     Pixel_f* img_pxls;
00155 
00156     create_image_f(img_out, num_rows, num_cols);
00157     img_pxls = *((*img_out)->pxls);
00158     num_pxls = num_rows*num_cols;
00159 
00160     for (pxl = 0; pxl < num_pxls; pxl++)
00161     {
00162         img_pxls[ pxl ] = val;
00163     }
00164 }
00165 
00186 void create_zero_image_f
00187 (
00188     Image_f** img_out, 
00189     uint32_t  num_rows, 
00190     uint32_t  num_cols
00191 )
00192 {
00193     Pixel_f p = {0};
00194 
00195     create_init_image_f(img_out, num_rows, num_cols, p);
00196 }
00197 
00228 void create_random_image_f
00229 (
00230     Image_f** img_out, 
00231     uint32_t  num_rows, 
00232     uint32_t  num_cols,
00233     Pixel_f   min,
00234     Pixel_f   max
00235 )
00236 {
00237     uint32_t num_pxls;
00238     uint32_t pxl;
00239     Pixel_f* img_pxls;
00240     float    x;
00241 
00242     create_image_f(img_out, num_rows, num_cols);
00243     img_pxls = *((*img_out)->pxls);
00244     num_pxls = num_rows*num_cols;
00245 
00246     for (pxl = 0; pxl < num_pxls; pxl++)
00247     {
00248         x = (float)rand() / (float)RAND_MAX;
00249         img_pxls[ pxl ].r = min.r + (max.r - min.r)*x;
00250         x = (float)rand() / (float)RAND_MAX;
00251         img_pxls[ pxl ].g = min.g + (max.g - min.r)*x;
00252         x = (float)rand() / (float)RAND_MAX;
00253         img_pxls[ pxl ].b = min.b + (max.b - min.b)*x;
00254     }
00255 }
00256 
00281 Error* create_image_from_matrices_f
00282 (
00283     Image_f**   img_out, 
00284     const Matrix_f* m_r,
00285     const Matrix_f* m_g,
00286     const Matrix_f* m_b
00287 )
00288 {
00289     uint32_t num_elts;
00290     uint32_t elt;
00291     Pixel_f* img_pxls;
00292     float*   m_r_elts;
00293     float*   m_g_elts;
00294     float*   m_b_elts;
00295 
00296     if (m_r->num_rows != m_g->num_rows || m_g->num_rows != m_b->num_rows ||
00297         m_r->num_cols != m_g->num_cols || m_g->num_cols != m_b->num_cols)
00298     {
00299         free_image_f(*img_out); *img_out = NULL;
00300         return JWSC_EARG("Inconsistent image channel sizes");
00301     }
00302 
00303     create_image_f(img_out, m_r->num_rows, m_r->num_cols);
00304 
00305     img_pxls = *((*img_out)->pxls);
00306     m_r_elts = *(m_r->elts);
00307     m_g_elts = *(m_g->elts);
00308     m_b_elts = *(m_b->elts);
00309 
00310     num_elts = m_r->num_rows*m_r->num_cols;
00311 
00312     for (elt = 0; elt < num_elts; elt++)
00313     {
00314         img_pxls[ elt ].r = m_r_elts[ elt ];
00315         img_pxls[ elt ].g = m_g_elts[ elt ];
00316         img_pxls[ elt ].b = m_b_elts[ elt ];
00317     }
00318 
00319     return NULL;
00320 }
00321 
00340 void create_image_from_matrix_f
00341 (
00342     Image_f**   img_out, 
00343     const Matrix_f* m
00344 )
00345 {
00346     create_image_from_matrices_f(img_out, m, m, m);
00347 }
00348 
00373 void create_matrices_from_image_f
00374 (
00375     Matrix_f**     m_r_out, 
00376     Matrix_f**     m_g_out, 
00377     Matrix_f**     m_b_out, 
00378     const Image_f* img
00379 )
00380 {
00381     uint32_t num_elts;
00382     uint32_t elt;
00383     Pixel_f* img_pxls;
00384     float*   m_r_elts;
00385     float*   m_g_elts;
00386     float*   m_b_elts;
00387 
00388     create_matrix_f(m_r_out, img->num_rows, img->num_cols);
00389     create_matrix_f(m_g_out, img->num_rows, img->num_cols);
00390     create_matrix_f(m_b_out, img->num_rows, img->num_cols);
00391 
00392     m_r_elts = *((*m_r_out)->elts);
00393     m_g_elts = *((*m_g_out)->elts);
00394     m_b_elts = *((*m_b_out)->elts);
00395     img_pxls = *(img->pxls);
00396 
00397     num_elts = img->num_rows*img->num_cols;
00398 
00399     for (elt = 0; elt < num_elts; elt++)
00400     {
00401         m_r_elts[ elt ] = img_pxls[ elt ].r;
00402         m_g_elts[ elt ] = img_pxls[ elt ].g;
00403         m_b_elts[ elt ] = img_pxls[ elt ].b;
00404     }
00405 }
00406 
00437 void create_matrix_from_image_f
00438 (
00439     Matrix_f**     m_out, 
00440     const Image_f* img,
00441     float          r_weight,
00442     float          g_weight,
00443     float          b_weight
00444 )
00445 {
00446     uint32_t num_elts;
00447     uint32_t elt;
00448     float    weight_sum;
00449     float*   m_elts;
00450     Pixel_f* img_pxls;
00451 
00452     assert(r_weight >= 0 && g_weight >= 0 && b_weight >= 0);
00453 
00454     if ((weight_sum = r_weight + g_weight + b_weight) != 1.0)
00455     {
00456         r_weight *= 1.0 / weight_sum;
00457         g_weight *= 1.0 / weight_sum;
00458         b_weight *= 1.0 / weight_sum;
00459     }
00460 
00461     create_matrix_f(m_out, img->num_rows, img->num_cols);
00462 
00463     m_elts   = *((*m_out)->elts);
00464     img_pxls = *(img->pxls);
00465 
00466     num_elts = img->num_rows*img->num_cols;
00467 
00468     for (elt = 0; elt < num_elts; elt++)
00469     {
00470         m_elts[ elt ] = r_weight*img_pxls[ elt ].r +
00471                         g_weight*img_pxls[ elt ].g +
00472                         b_weight*img_pxls[ elt ].b;
00473     }
00474 }
00475 
00493 void copy_image_f(Image_f** img_out, const Image_f* img_in)
00494 {
00495     uint32_t num_pxls;
00496     uint32_t pxl;
00497     Pixel_f* img_out_pxls;
00498     Pixel_f* img_in_pxls;
00499 
00500     create_image_f(img_out, img_in->num_rows, img_in->num_cols);
00501 
00502     img_out_pxls = *((*img_out)->pxls);
00503     img_in_pxls  = *(img_in->pxls);
00504 
00505     num_pxls = img_in->num_rows*img_in->num_cols;
00506 
00507     for (pxl = 0; pxl < num_pxls; pxl++ )
00508     {
00509         img_out_pxls[ pxl ] = img_in_pxls[ pxl ];
00510     }
00511 }
00512 
00526 void free_image_f(Image_f* img)
00527 {
00528     if (img == NULL) return;
00529 
00530     free(*(img->pxls));
00531     free(img->pxls);
00532     free(img);
00533 }
00534