Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phHistogramData.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission :
00003         Realtime Vision Processing System
00004 
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008 
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <phHistogramData.h>
00033 
00034 #if USE_FILETYPE
00035 #else
00036     //#include <sys/file.h>
00037     #include <sys/types.h>
00038     #include <sys/stat.h>
00039     #include <fcntl.h>
00040     //#include <unistd.h>
00041 #endif
00042 #include <math.h>
00043 
00044 #include <phError.h>
00045 #include <phFile.h>
00046 #include <phMemory.h>
00047 #include <phPrint.h>
00048 
00049 #ifdef __cplusplus
00050 extern "C" {
00051 #endif
00052 
00053 /* ---------------------------------------------------------------------- */
00054 #define HSV_TIMESTUFF() 0
00055 /* ---------------------------------------------------------------------- */
00056 /* find the actual index of the bin within the nbins range */
00057 #define PH_HISTOGRAM_DATA_BIN_INDEX(bin,binstep) \
00058         ((bin - (bin % binstep)) / binstep);
00059 
00060 #define PH_HISTOGRAM_DATA_BIN_MINVALUE(bin,binwidth) \
00061         ((uint32_t)(bin * binwidth))
00062         
00063 #define PH_HISTOGRAM_DATA_BIN_MAXVALUE(bin,binwidth) \
00064         ((uint32_t)((bin+1) * binwidth) - 1)
00065 
00066 /* ---------------------------------------------------------------------- */
00067 int ph_histogram_data_gen_from_image(const uint32_t width,
00068                                      const uint32_t height,
00069                                      const uint32_t depth,
00070                                      const uint8_t  *img,
00071                                      
00072                                      uint32_t x1,
00073                                      uint32_t y1,
00074                                      uint32_t x2,
00075                                      uint32_t y2,
00076                                      
00077                                      const uint32_t nbins,
00078                                      const float    max_element_value,
00079                                      uint32_t       **pbinVal,
00080                                      uint32_t       *pbinVal_size,
00081                                      uint32_t       **pbinCnt,
00082                                      uint32_t       *pbinCnt_size,
00083                                      uint32_t       **pbinAvg,
00084                                      uint32_t       *pbinAvg_size )
00085 {
00086     phFUNCTION("ph_histogram_data_gen_from_image")
00087 
00088     const double    multiple    = ((double)nbins)/(max_element_value+1.0);
00089     const uint32_t  binelements = nbins * depth;
00090     
00091     uint32_t        *avgarray   = NULL;
00092     uint32_t        *cntarray   = NULL;
00093     uint32_t        *valarray   = NULL;
00094 
00095     uint32_t        row         = 0;
00096     uint32_t        pixel       = 0;
00097 
00098     uint32_t    w, h, d         = 0;
00099     uint32_t    bin             = 0; /* actual index into array where 
00100                                       * bin is: ibin * d */
00101 #if HSV_TIMESTUFF()
00102     phTime  timedb("ph_histogram_data_gen_from_image");
00103 #endif /* HSV_TIMESTUFF() */
00104 
00105 #if HSV_TIMESTUFF()
00106     timedb.start("memory allocs");
00107 #endif
00108     /* DON'T ASSUME THAT bin count won't change. Reallocate these.*/
00109     /* OR make a maximum size, and just leave them here.*/
00110     phDALLOC( *pbinVal, *pbinVal_size, binelements, uint32_t );
00111     phDALLOC( *pbinCnt, *pbinCnt_size, binelements, uint32_t );
00112     phDALLOC( *pbinAvg, *pbinAvg_size, binelements, uint32_t );
00113 #if HSV_TIMESTUFF()
00114     timedb.stop();
00115 #endif
00116 
00117     /* This is easier than dereferencing the float pointer all the time */
00118     avgarray = *pbinAvg;
00119     cntarray = *pbinCnt;
00120     valarray = *pbinVal;
00121     
00122     /* make sure Y coords are within bounds */
00123     if (y2 >= height)
00124         y2 = height-1;
00125     if (y1 >= y2)
00126         y1 = y2 - 1;
00127 
00128     /* make sure the X coords are within bounds */
00129     if (x2 >= width)
00130         x2 = width-1;
00131     if (x1 >= x2)
00132         x1 = x2 - 1;
00133         
00134     /* First, generate the histogram */
00135     for (h = y1; h <= y2; h++)
00136     {
00137         row = h * width;
00138         for (w = x1; w <= x2; w++) 
00139         {
00140             pixel = (row + w) * depth;
00141             for (d = 0; d < depth; d++) 
00142             {
00143                 bin = ((uint32_t)floor(img[pixel + d] * multiple)) * depth + d;
00144                 valarray[ bin ] += img[pixel + d];
00145                 cntarray[ bin ]++;
00146             }
00147         }
00148     }
00149 
00150 #if HSV_TIMESTUFF()
00151     timedb.report();
00152 #endif
00153     return phSUCCESS;
00154 error:
00155     return phFAIL;
00156 }
00157 
00158 /* ---------------------------------------------------------------------- */
00159 int ph_histogram_data_gen_max( const uint32_t   nbins,
00160                                const uint32_t   binstep,
00161                                const uint32_t   format,
00162                                const float      max_element_value,
00163                                const uint32_t  *valarray,
00164                                const uint32_t  *cntarray,
00165                                uint32_t        *avgarray,
00166                                phColor         *pmaxbin_color,
00167                                phColor         *pmaxbin_threshold,
00168                                uint32_t       **pmaxBin,
00169                                uint32_t        *pmaxBin_size,
00170                                uint32_t       **pmaxCnt,
00171                                uint32_t        *pmaxCnt_size,
00172                                uint32_t       **pmaxAvg,
00173                                uint32_t        *pmaxAvg_size )
00174 {
00175     phFUNCTION("ph_histogram_data_gen_max")
00176 
00177     const double    binwidth= (max_element_value + 1.0) / (double)nbins;
00178     const double    multiple = ((double)nbins) / (max_element_value + 1.0);
00179     const uint32_t  binElems = nbins * binstep;
00180 
00181     uint32_t d  = 0;
00182     uint32_t bin= 0;
00183     
00184     uint32_t *maxAvg= NULL;
00185     uint32_t *maxCnt= NULL;
00186     uint32_t *maxBin= NULL;
00187 
00188     /* These are used to calculate the maxbin color/threshold */
00189     uint32_t index  = 0;
00190     uint32_t lower  = 0;
00191     uint32_t upper  = 0;
00192     uint32_t mid    = 0;
00193     uint32_t thr    = (uint32_t)(binwidth / 2);
00194     
00195     phColor maxbin_color;
00196     phColor maxbin_threshold;
00197 
00198     /* TODO: check parameters */
00199 
00200     /* make sure there is enough room in the max arrays */
00201     phDALLOC( *pmaxAvg, *pmaxAvg_size, binstep, uint32_t);
00202     phDALLOC( *pmaxCnt, *pmaxCnt_size, binstep, uint32_t);
00203     phDALLOC( *pmaxBin, *pmaxBin_size, binstep, uint32_t);
00204 
00205     maxAvg = *pmaxAvg;
00206     maxCnt = *pmaxCnt;
00207     maxBin = *pmaxBin;
00208     
00209     for (bin = 0; bin < binElems; bin++) 
00210     {
00211         /* This calculates the average */
00212         if (cntarray[ bin ]) 
00213         {
00214             avgarray[ bin ] = valarray[ bin ] / cntarray[ bin ];
00215         }
00216         
00217         index = bin % binstep;
00218         if (cntarray[ bin ] > maxCnt[index])
00219         {
00220             maxBin[index] = bin;
00221             maxAvg[index] = avgarray[ bin ];
00222             maxCnt[index] = cntarray[ bin ];
00223         }
00224     }
00225 
00226     /* This calculates the middle value of the maxbins and returns 
00227      * the threshold to match the values that fall in the maxbins */
00228     for (d = 0; (d < binstep) && (d < 4); d++ )
00229     {
00230         /* The index of the max bin out of nbins */
00231         index   = PH_HISTOGRAM_DATA_BIN_INDEX(maxBin[d],binstep);
00232         lower   = PH_HISTOGRAM_DATA_BIN_MINVALUE(index,binwidth);
00233         upper   = PH_HISTOGRAM_DATA_BIN_MAXVALUE(index,binwidth);
00234         mid     = (upper + lower) / 2;
00235         
00236         maxbin_color.array.v[d]     = mid;
00237         maxbin_threshold.array.v[d] = thr;
00238     }
00239 
00240     /* set the type of the maxbin_color/threshold structs */
00241     maxbin_color.type = 
00242     maxbin_threshold.type = phImageFormatToColorType(format);
00243 
00244     *pmaxbin_color      = maxbin_color;
00245     *pmaxbin_threshold  = maxbin_threshold;
00246 
00247     return phSUCCESS;
00248 error:
00249     return phFAIL;
00250 }
00251 
00252 /* ---------------------------------------------------------------------- */
00253 int ph_histogram_data_bin_regions( const uint32_t nbins,
00254                                    const uint32_t binstep,
00255                                    const uint32_t format,
00256                                    const float    max_element_value,
00257                                    const uint32_t val_percent_cutoff,
00258                                    const uint32_t max_bin_breaks,
00259                                    const uint32_t *valarray,
00260                                    const uint32_t *cntarray,
00261                                    const uint32_t *avgarray,
00262                                    const uint32_t *maxBin,
00263                                    const uint32_t *maxCnt,
00264                                    const uint32_t *maxAvg,
00265                                    phColor        *pcolor,
00266                                    phColor        *pthreshold )
00267 {
00268     phFUNCTION("ph_histogram_data_bin_regions")
00269 
00270     const double    binwidth= (max_element_value+1.0) / (double)nbins;
00271     const double    multiple = ((double)nbins) / (max_element_value+1.0);
00272     const uint32_t  binElems = nbins * binstep;
00273     double          valueprct= 0.03;/*3.0/100.0;*//* 3 percent */
00274     
00275     uint32_t    valuelimit  = 0;
00276 
00277     uint32_t    b           = 0;
00278     uint32_t    d           = 0;
00279     uint32_t    bin         = 0;
00280     uint32_t    done        = 0;
00281     uint32_t    bin_breaks  = 0;
00282 
00283     /* These are used in to calculate the range or colors and threshold */
00284     uint32_t    value       = 0;
00285     uint32_t    limit       = 0;
00286     uint32_t    step        = 0;
00287     int32_t     maxindex    = 0;
00288     int32_t     maxvalue    = 0;
00289     int32_t     minindex    = 0;
00290     int32_t     minvalue    = 0;
00291     int32_t     c = 0;
00292     int32_t     t = 0;
00293     
00294     
00295     phColor color;
00296     phColor threshold;
00297     
00298     /* TODO: check parameters */
00299 
00300     if (val_percent_cutoff > 0.0)
00301     {
00302         valueprct = ((double)val_percent_cutoff) / 100.0;
00303     }
00304     
00305     /* This is the code for the calculation of the range of colors
00306      * surrounding the maxbin and the middle color value within
00307      * the range along with the threshold value to cover that
00308      * matched range */
00309     
00310     /* Calculate the threshold by searching around the max bin location, to
00311      * some threshold, and calculating the deviation */
00312     for (d = 0; (d < binstep) && (d < 4); d++ )
00313     {
00314         step  = binstep;
00315         valuelimit = (uint32_t)(((float)cntarray[maxBin[d]]) * valueprct);
00316         
00317         /* Search to the minimum -------------------------------------------- */
00318         done        = 0;
00319         bin         = 0;
00320         bin_breaks  = 0;
00321         limit       = 0;
00322         /* Look for an edge or minima in the bins less than maxbin */
00323         bin = maxBin[d];
00324         while ((bin >= limit) && (!done))
00325         {
00326             value = cntarray[bin];
00327             
00328             if ((value <= 0) || (value <= valuelimit)) 
00329                 bin_breaks++;
00330             else
00331                 bin_breaks = 0;
00332             
00333             if ((bin_breaks > max_bin_breaks) || (bin < binstep))
00334                 done = 1;
00335 
00336             if (!done)
00337                 bin -= step;
00338             else
00339                 bin += step * bin_breaks;
00340         }
00341         minindex = PH_HISTOGRAM_DATA_BIN_INDEX(bin,binstep);
00342         minvalue = PH_HISTOGRAM_DATA_BIN_MINVALUE(minindex,binwidth);
00343         /* ------------------------------------------------------------------ */
00344         
00345         /* Search to the maximum -------------------------------------------- */
00346         done        = 0;
00347         bin         = 0;
00348         bin_breaks  = 0;
00349         limit       = (binElems - binstep);
00350         /* Look for an edge or minima in the bins greater than maxbin */
00351         bin = maxBin[d];
00352         while ((bin < binElems) && (!done))
00353         {
00354             value = cntarray[bin];
00355             
00356             if ((value <= 0) || (value <= valuelimit)) 
00357                 bin_breaks++;
00358             else
00359                 bin_breaks = 0;
00360             
00361             if ((bin_breaks > max_bin_breaks) || (bin > limit))
00362                 done = 1;
00363             
00364             if (!done) 
00365                 bin += step;
00366             else
00367                 bin -= step * bin_breaks;
00368         }
00369         maxindex = PH_HISTOGRAM_DATA_BIN_INDEX(bin,binstep);
00370         maxvalue = PH_HISTOGRAM_DATA_BIN_MAXVALUE(maxindex,binwidth);
00371         /* ------------------------------------------------------------------ */
00372 
00373         /* Set the mid range of color values and the threshold to cover it */
00374         t =(maxvalue - minvalue) / 2;
00375         c =(maxvalue + minvalue) / 2;
00376         threshold.array.v[d]= t;
00377         color.array.v[d]    = c;
00378     }
00379 
00380     /* The phImage* defines are indexed in the same order as the phColor* defines */
00381     /* This allows this function to be used for translating the format flag value 
00382        into a color value index as well */
00383     /* Set the type for all the phColor variables */
00384     color.type = threshold.type = phImageFormatToColorType(format);
00385 
00386     *pcolor     = color;
00387     *pthreshold = threshold;
00388     return phSUCCESS;
00389 #if 0
00390 error:
00391     return phFAIL;
00392 #endif
00393 }
00394 
00395 /* ---------------------------------------------------------------------- */
00396 #define phHISTOGRAM_ADD 1
00397 #define phHISTOGRAM_SUB 2
00398 int ph_histogram_data_compute( const uint32_t   op,
00399                                const uint32_t   nbins_one,
00400                                const uint32_t   binstep_one,
00401                                const uint32_t   binelems_one,
00402                                const uint32_t   nbins_two,
00403                                const uint32_t   binstep_two,
00404                                const uint32_t   binelems_two,
00405                                uint32_t        *binVal_one,
00406                                uint32_t        *binCnt_one,
00407                                uint32_t        *binVal_two,
00408                                uint32_t        *binCnt_two,
00409                                uint32_t        *binVal_out,
00410                                uint32_t        *binCnt_out  )
00411 {
00412     phFUNCTION("ph_histogram_data_compute")
00413     uint32_t    a       = 0;
00414     uint32_t    b       = 0;
00415     uint32_t    i       = 0;
00416     int         retrc   = phSUCCESS;
00417 
00418     if ((nbins_one     == nbins_two)     &&
00419         (binstep_one   == binstep_two)   &&
00420         (binelems_one  == binelems_two))
00421     {
00422         if (op == phHISTOGRAM_ADD)
00423         {
00424             for (i = 0; i < binelems_one; i++ )
00425             {
00426                 a = binVal_one[i] + binVal_two[i];
00427                 b = binCnt_one[i] + binCnt_two[i];
00428                 binVal_out[i] = a;
00429                 binCnt_out[i] = b;
00430             }
00431         }
00432         else if (op == phHISTOGRAM_SUB)
00433         {
00434             for (i = 0; i < binelems_one; i++ )
00435             {
00436                 a = binVal_one[i] - binVal_two[i];
00437                 b = binCnt_one[i] - binCnt_two[i];
00438                 binVal_out[i] = a;
00439                 binCnt_out[i] = b;
00440             }
00441         }
00442         else
00443         {
00444             phERR_PRINT("Unknown op. Valid parameters: phHISTOGRAM_ADD, phHISTOGRAM_SUB\n");
00445             retrc = phFAIL;
00446         }
00447     }
00448     else
00449     {
00450         phERR_PRINT("Not performing operation on unmatched histogram\n");
00451         phPROGRESS("\n\nbins:t%u != %u - binstep:%u != %u - binelems:%u != %u\n",
00452                     nbins_one,      nbins_two,
00453                     binstep_one,    binstep_two,
00454                     binelems_one,   binelems_two );
00455         retrc = phFAIL;
00456     }
00457 
00458     return retrc;
00459 }
00460 
00461 #ifdef __cplusplus
00462 }
00463 #endif
00464 
00465 /* ---------------------------------------------------------------------- */
00466 phHistogramData::phHistogramData()
00467 {
00468     this->init();
00469 }
00470 
00471 /* ---------------------------------------------------------------------- */
00472 phHistogramData::phHistogramData( const phHistogramData &hist )
00473 {
00474     phFUNCTION("phHistogramData::phHistogramData")
00475     phHistogramData *histptr = (phHistogramData *)&hist;
00476 
00477     rc = this->lock();
00478     phPRINT_RC(rc,NULL,"lock");
00479 
00480     this->init();
00481     
00482     rc = this->copy(histptr);
00483     phPRINT_RC(rc,NULL,"this->copy(histptr);");
00484     
00485     rc = this->unlock();
00486     phPRINT_RC(rc,NULL,"unlock");
00487 }
00488 
00489 /* ---------------------------------------------------------------------- */
00490 phHistogramData::~phHistogramData()
00491 {
00492     phFUNCTION("phHistogramData::~phHistogramData")
00493 
00494     rc = this->lock();
00495     phPRINT_RC(rc,NULL,"lock");
00496 
00497     phFree(this->m_binVal);
00498     phFree(this->m_binCnt);
00499     phFree(this->m_binAvg);
00500     phFree(this->m_maxAvg);
00501     phFree(this->m_maxCnt);
00502     phFree(this->m_maxBin);
00503 
00504     rc = this->unlock();
00505     phPRINT_RC(rc,NULL,"unlock");
00506 }
00507 
00508 /* ---------------------------------------------------------------------- */
00509 void phHistogramData::init()
00510 {
00511     phFUNCTION("phHistogramData::init")
00512 
00513     rc = this->lock();
00514     phPRINT_RC(rc,NULL,"lock");
00515         
00516     this->m_binCount= 0;
00517     this->m_binStep   = 0;
00518     this->m_binElems= 0; 
00519     this->m_binVal = NULL;
00520     this->m_binCnt = NULL;
00521     this->m_binAvg = NULL;
00522     this->m_maxAvg = NULL;
00523     this->m_maxCnt = NULL;
00524     this->m_maxBin = NULL;
00525 
00526     this->m_binVal_size = 0;
00527     this->m_binCnt_size = 0;
00528     this->m_binAvg_size = 0;
00529     this->m_maxAvg_size = 0;
00530     this->m_maxCnt_size = 0;
00531     this->m_maxBin_size = 0;
00532 
00533     this->m_binElems = 0;
00534 
00535     this->m_image_height = 120;
00536 
00537     this->setName("phHistogramData");
00538 
00539     rc = this->unlock();
00540     phPRINT_RC(rc,NULL,"unlock");
00541 }
00542 
00543 /* ---------------------------------------------------------------------- */
00544 int phHistogramData::copy( phObject *copyto_object )
00545 {
00546     phFUNCTION("phHistogramData::copy")
00547     
00548     if (this->isNamed(((phObject *)copyto_object)->getName()))
00549     {
00550         phHistogramData *hist = (phHistogramData *)copyto_object;
00551         return hist->copy(*this);
00552     }
00553     /* Otherwise I'll assume they are incompatible */
00554     else
00555     {
00556         phPRINT_RC(-1,NULL, "Invalid object pairing in update."
00557                           "[ this:%s != target:%s ]",
00558                  this->getName(), ((phObject *)copyto_object)->getName());
00559         return phFAIL;
00560     }
00561 }
00562 
00563 /* ---------------------------------------------------------------------- */
00564 int phHistogramData::swap( phObject *object )
00565 {
00566     phFUNCTION("phHistogramData::swap")
00567 
00568     if (this->isNamed(((phObject *)object)->getName()))
00569     {
00570         phHistogramData *hist = (phHistogramData *)object;
00571 
00572         return hist->copy(*this);
00573     }
00574     /* Otherwise I'll assume they are incompatible */
00575     else
00576     {
00577         phPRINT_RC(-1,NULL, "Invalid object pairing in update."
00578                           "[ this:%s != target:%s ]",
00579                  this->getName(), ((phObject *)object)->getName());
00580         return phFAIL;
00581     }    
00582 }
00583 
00584 /* ---------------------------------------------------------------------- */
00585 int phHistogramData::updateFromBins()
00586 {
00587     phFUNCTION("phHistogramData::updateFromBins")
00588     int locked = 0;
00589 
00590     phTHIS_LOCK(locked);
00591    
00592     /* compute average; generate max bin info; create max color info */
00593     ph_histogram_data_gen_max(this->m_binCount, 
00594                               this->m_binStep,
00595                               phColorToFormat(this->m_color),
00596                               255.0,
00597                               this->m_binVal,
00598                               this->m_binCnt,
00599                               /* the following are returned/altered/allocated */
00600                               this->m_binAvg,
00601                               &this->m_maxbin_color,&this->m_maxbin_threshold,
00602                               &this->m_maxBin,      &this->m_maxBin_size,
00603                               &this->m_maxCnt,      &this->m_maxCnt_size,
00604                               &this->m_maxAvg,      &this->m_maxAvg_size );
00605     phPRINT_RC(rc,NULL,"ph_histogram_data_gen_max");
00606 
00607     rc = ph_histogram_data_bin_regions(this->m_binCount, 
00608                                        this->m_binStep,
00609                                        phColorToFormat(this->m_color), 
00610                                        255.0,
00611                                        2, /* percent of the max bin count */
00612                                        1, /* maximum # of breaks when searching */
00613                                        this->m_binVal, this->m_binCnt, this->m_binAvg,
00614                                        this->m_maxBin, this->m_maxCnt, this->m_maxAvg,
00615                                        /* the following are returned/altered */
00616                                        &this->m_color, &this->m_threshold );
00617     phPRINT_RC(rc,NULL,"ph_histogram_regions");
00618 
00619     phTHIS_UNLOCK(locked);
00620 
00621     return phSUCCESS;
00622 error:
00623     phTHIS_ERROR_UNLOCK(locked);
00624 
00625     return phFAIL;
00626 }
00627 
00628 
00629 
00630 /* ---------------------------------------------------------------------- */
00631 int phHistogramData::setData(uint32_t binCount,
00632                              uint32_t binStep,
00633                              uint32_t *binVal,
00634                              uint32_t *binCnt )
00635 {
00636     phFUNCTION("phHistogramData::setData")
00637 
00638     rc = this->lock();
00639     phPRINT_RC(rc,NULL,"lock");
00640    
00641     this->m_binCount    = binCount;
00642     this->m_binStep     = binStep;
00643     this->m_binElems    = binCount * binStep;
00644   
00645     if (this->m_binElems > 0)
00646     {
00647         phDALLOC_RESIZE(this->m_binCnt,this->m_binCnt_size,
00648                         this->m_binElems,uint32_t);
00649         phDALLOC_RESIZE(this->m_binVal,this->m_binVal_size,
00650                         this->m_binElems,uint32_t);
00651         phDALLOC_RESIZE(this->m_binAvg,this->m_binAvg_size,
00652                         this->m_binElems,uint32_t);
00653 
00654         phMemmove(this->m_binVal, binVal, this->m_binVal_size);
00655         phMemmove(this->m_binCnt, binCnt, this->m_binCnt_size);
00656     }
00657     
00658     rc = this->updateFromBins();
00659     phPRINT_RC(rc,NULL,"updateFromBins()");
00660     
00661     rc = this->notify();
00662     phPRINT_RC(rc,NULL,"notify() failed.");
00663 
00664     rc = this->autoGenerateImage();
00665     phPRINT_RC(rc,NULL,"this->autoGenerateImage()");
00666     
00667     rc = this->unlock();
00668     phPRINT_RC(rc,NULL,"unlock");
00669 
00670     return phSUCCESS;
00671 error:
00672     rc = this->unlock();
00673     phPRINT_RC(rc,NULL,"unlock");
00674 
00675     return phFAIL;
00676 }
00677 
00678 /* ---------------------------------------------------------------------- */
00679 int phHistogramData::setData(uint32_t binCount,
00680                              uint32_t binstep,
00681                              phColor maxbin_color,
00682                              phColor maxbin_threshold,
00683                              phColor color,
00684                              phColor threshold,
00685                              uint32_t *binVal,
00686                              uint32_t *binCnt,
00687                              uint32_t *binAvg,
00688                              uint32_t *maxBin,
00689                              uint32_t *maxAvg,
00690                              uint32_t *maxCnt )
00691 {
00692     phFUNCTION("phHistogramData::setData")
00693 
00694     rc = this->lock();
00695     phPRINT_RC(rc,NULL,"lock");
00696    
00697     this->m_binCount    = binCount;
00698     this->m_binStep     = binstep;
00699     this->m_binElems    = binCount * binstep;
00700   
00701     this->m_maxbin_color        = maxbin_color;
00702     this->m_maxbin_threshold    = maxbin_threshold;
00703     this->m_color               = color;
00704     this->m_threshold           = threshold;
00705   
00706     if (this->m_binElems > 0)
00707     {
00708         phDALLOC_RESIZE(this->m_binCnt,this->m_binCnt_size,
00709                         this->m_binElems,uint32_t);
00710         phDALLOC_RESIZE(this->m_binVal,this->m_binVal_size,
00711                         this->m_binElems,uint32_t);
00712         phDALLOC_RESIZE(this->m_binAvg,this->m_binAvg_size,
00713                         this->m_binElems,uint32_t);
00714         phDALLOC_RESIZE(this->m_maxAvg,this->m_maxAvg_size,
00715                         this->m_binStep,uint32_t);
00716         phDALLOC_RESIZE(this->m_maxCnt,this->m_maxCnt_size,
00717                         this->m_binStep,uint32_t);
00718         phDALLOC_RESIZE(this->m_maxBin,this->m_maxBin_size,
00719                         this->m_binStep,uint32_t);
00720 
00721         phMemmove(this->m_binVal, binVal, this->m_binVal_size);
00722         phMemmove(this->m_binCnt, binCnt, this->m_binCnt_size);
00723         phMemmove(this->m_binAvg, binAvg, this->m_binAvg_size);
00724         phMemmove(this->m_maxAvg, maxAvg, this->m_maxAvg_size);
00725         phMemmove(this->m_maxCnt, maxCnt, this->m_maxCnt_size);
00726         phMemmove(this->m_maxBin, maxBin, this->m_maxBin_size);
00727     }
00728     
00729     rc = this->notify();
00730     phPRINT_RC(rc,NULL,"notify() failed.");
00731     
00732     rc = this->autoGenerateImage();
00733     phPRINT_RC(rc,NULL,"this->autoGenerateImage()");
00734     
00735     rc = this->unlock();
00736     phPRINT_RC(rc,NULL,"unlock");
00737 
00738     return phSUCCESS;
00739 error:
00740     rc = this->unlock();
00741     phPRINT_RC(rc,NULL,"unlock");
00742 
00743     return phFAIL;
00744 }
00745 
00746 /* ---------------------------------------------------------------------- */
00747 int phHistogramData::copy( phHistogramData &copyfrom )
00748 {
00749     phFUNCTION("phHistogramData::copy")
00750 
00751     rc = this->lock();
00752     phPRINT_RC(rc,NULL,"lock");
00753 
00754     rc = copyfrom.lock();
00755     phPRINT_RC(rc,NULL,"copyfrom.lock");
00756     rc = this->setData( copyfrom.m_binCount,
00757                         copyfrom.m_binStep,
00758                         copyfrom.m_maxbin_color,
00759                         copyfrom.m_maxbin_threshold,
00760                         copyfrom.m_color,
00761                         copyfrom.m_threshold,
00762                         copyfrom.m_binVal,
00763                         copyfrom.m_binCnt,
00764                         copyfrom.m_binAvg,
00765                         copyfrom.m_maxBin,
00766                         copyfrom.m_maxAvg,
00767                         copyfrom.m_maxCnt
00768                         );
00769     phPRINT_RC(rc,NULL,"copyfrom.setData");
00770    
00771     rc = copyfrom.unlock();
00772     phPRINT_RC(rc,NULL,"copyfrom.unlock");
00773     
00774     rc = this->unlock();
00775     phPRINT_RC(rc,NULL,"unlock");
00776 
00777     return phSUCCESS;
00778 }
00779 
00780 /* ---------------------------------------------------------------------- */
00781 phHistogramData &phHistogramData::operator =( phHistogramData &right )
00782 {
00783     phFUNCTION("phHistogramData::operator =")
00784 
00785     if (&right != this)
00786     {
00787         rc = this->copy(right);
00788         phPRINT_RC(rc,NULL,"this->copy(right);");
00789     }
00790 
00791     return *this;
00792 }
00793 
00794 /* ---------------------------------------------------------------------- */
00795 phHistogramData &phHistogramData::operator +=( phHistogramData &right )
00796 {
00797     phFUNCTION("phHistogramData::operator +=")
00798     
00799     int locked      = 0;
00800     int right_locked= 0;
00801     
00802     phTHIS_LOCK(locked);
00803     phMUTEX_LOCK(right,right_locked);
00804     
00805     rc = ph_histogram_data_compute( phHISTOGRAM_ADD,
00806                                     this->m_binCount,/* one */
00807                                     this->m_binStep,
00808                                     this->m_binElems,
00809                                     right.m_binCount,/* two */
00810                                     right.m_binStep,
00811                                     right.m_binElems,
00812                                     this->m_binCnt, /* one */
00813                                     this->m_binVal,
00814                                     right.m_binCnt, /* two */
00815                                     right.m_binVal,
00816                                     this->m_binCnt, /* out */
00817                                     this->m_binVal );
00818     phPRINT_RC(rc,NULL,"ph_histogram_data_compute");
00819     
00820     if (rc == phSUCCESS)
00821     {
00822         rc = this->updateFromBins();
00823         phPRINT_RC(rc,NULL,"updateFromBins()");
00824     
00825         rc = this->notify();
00826         phPRINT_RC(rc,NULL,"notify() failed.");
00827     
00828         rc = this->autoGenerateImage();
00829         phPRINT_RC(rc,NULL,"this->autoGenerateImage()");
00830     }
00831 
00832 error:
00833     phMUTEX_ERROR_UNLOCK(right,right_locked);
00834     phTHIS_ERROR_UNLOCK(locked);
00835     
00836     return *this;
00837 }
00838 
00839 /* ---------------------------------------------------------------------- */
00840 #if 0
00841 phHistogramData phHistogramData::operator +( phHistogramData &right )
00842 {
00843     phFUNCTION("phHistogramData::operator +")
00844     
00845     int locked      = 0;
00846     int right_locked= 0;
00847     
00848     return *this;
00849 }
00850 #endif
00851 
00852 /* ---------------------------------------------------------------------- */
00853 phHistogramData &phHistogramData::operator -=( phHistogramData &right )
00854 {
00855     phFUNCTION("phHistogramData::operator -=")
00856     
00857     int locked      = 0;
00858     int right_locked= 0;
00859     
00860     phTHIS_LOCK(locked);
00861     phMUTEX_LOCK(right,right_locked);
00862     
00863     rc = ph_histogram_data_compute( phHISTOGRAM_SUB,
00864                                     this->m_binCount,/* one */
00865                                     this->m_binStep,
00866                                     this->m_binElems,
00867                                     right.m_binCount,/* two */
00868                                     right.m_binStep,
00869                                     right.m_binElems,
00870                                     this->m_binCnt, /* one */
00871                                     this->m_binVal,
00872                                     right.m_binCnt, /* two */
00873                                     right.m_binVal,
00874                                     this->m_binCnt, /* out */
00875                                     this->m_binVal );
00876     phPRINT_RC(rc,NULL,"ph_histogram_data_compute");
00877 
00878     if (rc == phSUCCESS)
00879     {
00880         rc = this->updateFromBins();
00881         phPRINT_RC(rc,NULL,"updateFromBins()");
00882     
00883         rc = this->notify();
00884         phPRINT_RC(rc,NULL,"notify() failed.");
00885     
00886         rc = this->autoGenerateImage();
00887         phPRINT_RC(rc,NULL,"this->autoGenerateImage()");
00888     }
00889     
00890 error:
00891     phMUTEX_ERROR_UNLOCK(right,right_locked);
00892     phTHIS_ERROR_UNLOCK(locked);
00893     
00894     return *this;
00895 }
00896 
00897 /* ---------------------------------------------------------------------- */
00898 #if 0
00899 phHistogramData phHistogramData::operator -( phHistogramData &right )
00900 {
00901     phFUNCTION("phHistogramData::operator -")
00902     
00903     int locked      = 0;
00904     int right_locked= 0;
00905     
00906     return *this;
00907 }
00908 #endif
00909 
00910 /* ---------------------------------------------------------------------- */
00911 int phHistogramData::setImageHeight(uint32_t height)
00912 {
00913     phFUNCTION("phHistogramData::setImageHeight")
00914     int locked = 0;
00915     
00916     phTHIS_LOCK(locked);
00917 
00918     if (height == 0) height = 1;
00919     this->m_image_height = height;
00920     
00921     phTHIS_UNLOCK(locked);
00922     
00923     return phSUCCESS;
00924 error:
00925     phTHIS_ERROR_UNLOCK(locked);
00926     
00927     return phFAIL;
00928 }
00929     
00930 /* ---------------------------------------------------------------------- */
00931 int phHistogramData::autoGenerateImage( uint32_t height )
00932 {
00933     phFUNCTION("phHistogramData::autoGenerateImage")
00934     int locked      = 0;
00935     int img_locked  = 0;
00936     
00937     phTHIS_LOCK(locked);
00938     phWRITELOCK(this->m_image,img_locked);
00939 
00940     if (height == 0) height = this->m_image_height;
00941 
00942     if (this->m_image.hasClients())
00943     {
00944         rc = this->generateImage( height );
00945         phCHECK_RC(rc,NULL,"this->m_generateImage()");
00946     }
00947     
00948     phRWUNLOCK(this->m_image,img_locked);
00949     phTHIS_UNLOCK(locked);
00950     
00951     return phSUCCESS;
00952 error:
00953     phRWUNLOCK_ERROR(this->m_image,img_locked);
00954     phTHIS_ERROR_UNLOCK(locked);
00955     
00956     return phFAIL;
00957 }
00958     
00959 /* ---------------------------------------------------------------------- */
00960 int phHistogramData::generateImage(uint32_t height)
00961 {
00962     phFUNCTION("phHistogramData::generateImage")
00963 
00964     uint32_t    b   = 0;
00965     uint32_t    i   = 0; 
00966     uint32_t    j   = 0; 
00967     uint32_t    k   = 0; 
00968     uint32_t    x   = 0;
00969     uint32_t    y   = 0;
00970     uint32_t    max_value = 0;
00971     uint32_t    value = 0;
00972     
00973     uint32_t    nbins       = 0;
00974     uint32_t    bin_step    = 0;
00975     uint32_t    *bins       = NULL;
00976     uint32_t    *maxArr     = NULL;
00977     
00978     int         locked          = 0;
00979     int         img_locked      = 0;
00980     int         reenable_notify = 0;
00981     
00982     uint32_t    border          = 3;
00983     uint32_t    width           = 0;
00984     int32_t     format          = phImageRGB24;
00985     int32_t     imgdepth        = phImageFormatToDepth(format);
00986 
00987     uint32_t    indepth         = 0;
00988     
00989     uint8_t     *buf            = NULL;
00990     uint32_t    tw              = 0;
00991     uint32_t    th              = 0;
00992     uint32_t    tf              = phImageRGB24;
00993     uint32_t    ts              = 0;
00994 
00995     float       *scales         = NULL;
00996     float       scale           = 0.0;
00997     float       scaled_value    = 0.0;
00998 
00999     int32_t     c = 0;
01000     int32_t     l = 0;
01001     int32_t     u = 0;
01002     uint32_t    min = 0;
01003     uint32_t    max = 0;
01004     uint32_t    minbin = 0;
01005     uint32_t    maxbin = 0;
01006 
01007     int         scale_all = 0;
01008 
01009     float       binwidth = 0.0;
01010     float       multiple = 0.0;
01011 
01012     phColor     tmp_color           = phColorArray32_new(0,0,0,0);
01013     phColor     border_bar_color    = phColorRGB24_new(255,0,255);
01014     phColor     bin_bar_color       = phColorRGB24_new(255,255,255);
01015     phColor     maxbin_bar_color    = phColorRGB24_new(100,100,255);
01016     phColor     color_bar_color     = phColorRGB24_new(255,0,0);
01017     phColor     thresh_bar_color    = phColorRGB24_new(0,255,0);
01018 
01019     phTHIS_LOCK(locked);
01020     phWRITELOCK(this->m_image,img_locked);
01021     
01022     nbins       = this->getBinCount();
01023     bin_step    = this->getBinStep();
01024     binwidth    = (float)(256.0 / (double)nbins);
01025     multiple    = (float)(((double)nbins)/256.0);
01026     width       = nbins * bin_step + ((bin_step - 1) * border);
01027     
01028     if (height == 0) 
01029     {
01030         height = this->m_image_height;
01031     }
01032 
01033     if ((width == 0) || (height == 0)) goto error;
01034     
01035     scales = (float *)phCalloc(bin_step,sizeof(float));
01036     phCHECK_PTR(scales,"phCalloc","phCalloc failed.");
01037 
01038     /* We don't want to trigger a notify while we're working on the image */
01039     if (this->m_image.isNotifyEnabled())
01040     {
01041         this->m_image.disableNotify();
01042         reenable_notify = 1;
01043     }
01044   
01045     /* Allocate data in the m_image object */
01046     rc = this->m_image.allocate( width, height, format );
01047     phCHECK_RC(rc,NULL,"this->m_image.allocate(%d,%d,0x%08x)",
01048             width,height,format);
01049   
01050     /* Get all the data out of rht m_image object */
01051     rc = this->m_image.swapData(&tw,&th,&tf,&buf,&ts);
01052     phCHECK_RC(rc,NULL,"this->m_image.swapData()");
01053 
01054     /* Clear the image data */
01055     phMemset(buf,0,ts);
01056    
01057     /* Find the very maximum value in any of the bins*/
01058     maxArr = this->getMaxArray();
01059 
01060     /* Scale all of the channels by the maximum value of all the channels... */
01061     if (scale_all)
01062     {
01063         /* Loop through all channels */
01064         for (i = 0; (i < bin_step) && (maxArr); i++ )
01065             /* Check value with previous max_value */
01066             if (max_value < maxArr[i]) 
01067                 max_value = maxArr[i];
01068 
01069         /* Add one percent of the max value so 1 percent of the top of the image
01070            won't have the bins drawn on it; this leaves some of the color bar
01071            and threshold bars visible */
01072         max_value += (uint32_t)(((float)max_value) * 0.01);
01073 
01074         for (i = 0; (i < bin_step) && (maxArr); i++)
01075         {
01076             /* Calculate how much to scale the count value by */
01077             scales[i] = ((float)height) / ((float)max_value);
01078         }
01079     }
01080     /* Or scale the channels by the maximum value of each channel */
01081     {
01082          /* Loop through all channels */
01083         for (i = 0; (i < bin_step) && (maxArr); i++ )
01084         {
01085             max_value = maxArr[i];
01086             
01087             /* Add one percent of the max value so 1 percent of the top of the image
01088              * won't have the bins drawn on it; this leaves some of the color bar
01089              * and threshold bars visible */
01090             max_value += (uint32_t)(((float)max_value) * 0.01);
01091 
01092             /* Calculate how much to scale the count value by */
01093             scales[i] = ((float)height) / ((float)max_value);
01094         }
01095     }
01096     
01097     /* We want to create the drawing of the bin count array */
01098     bins = this->getBinCntArray();
01099 
01100     for ( i = 0; i < bin_step; i++ )
01101     {
01102         /* 1.) Draw the borders of the components */
01103         /* i >= 1, we only need to do the bars in the middle */
01104         if (i > 0)
01105         {
01106             x = (nbins * i) + ((i-1) * border);
01107             for (k = 0; k < height; k++ )
01108             {
01109                 for (b = 0; b < border; b++ )
01110                 {
01111                     phMemcpy(&(buf[(x + b + k * width) * imgdepth]),
01112                              border_bar_color.array.v,
01113                              imgdepth);
01114                 }
01115             }
01116         }
01117  
01118         /* 2.) Draw the threshold/range that will be blobbed */
01119         c = this->m_color.array.v[i];
01120         l = this->m_threshold.array.v[i];
01121         u = this->m_threshold.array.v[i];
01122         if ((c - l) < 0)
01123             min = 0;
01124         else if ((c - l) > 255)
01125             min = 255;
01126         else
01127             min = c - l;
01128         
01129         if ((c + l) < 0)
01130             max = 0;
01131         else if ((c + l) > 255)
01132             max = 255;
01133         else
01134             max = c + l;
01135                 
01136         minbin = (int32_t)(min * multiple);
01137         maxbin = (int32_t)(max * multiple);
01138 
01139         x = minbin + (i * nbins) + (i * border);
01140         for (j = minbin; j <= maxbin; j++ , x++ )
01141         {
01142             for (k = 0; k < height; k++ )
01143             {
01144                 phMemcpy(&(buf[(x + k * width) * imgdepth]),
01145                          thresh_bar_color.array.v,
01146                          imgdepth);
01147             }
01148         }
01149         
01150         /* 3.) Draw the center color matched information */
01151         x = (uint32_t)(((int32_t)(this->m_color.array.v[i] * multiple)) + 
01152                        (i * nbins) + 
01153                        (i * border));
01154         for (k = 0; k < height; k++ )
01155         {
01156             phMemcpy(&(buf[(x + k * width) * imgdepth]),
01157                      color_bar_color.array.v,
01158                      imgdepth);
01159         }
01160         
01161         /* 4.) Draw the bins */
01162         maxbin = PH_HISTOGRAM_DATA_BIN_INDEX(this->getMaxBin()[i],this->m_binStep);
01163         scale = scales[i];
01164         for ( j = 0; j < nbins; j++ )
01165         {
01166             value = (unsigned long int)bins[ (j * bin_step) + i ];
01167             
01168             x = ((i * nbins) + (i * border) + j);
01169             
01170             scaled_value = value * scale;
01171             y = (uint32_t)(scaled_value > height ? height : scaled_value);
01172             y = height - y;
01173 
01174             if (j == maxbin) 
01175                 tmp_color = maxbin_bar_color;
01176             else
01177                 tmp_color = bin_bar_color;
01178                         
01179             /* Create the bin bar */
01180             for (k = y; k <= height; k++ )
01181             {
01182                 if (k == height)
01183                 {
01184                     phMemcpy(&(buf[(x + (height - 1) * width)*imgdepth]),
01185                              tmp_color.array.v,
01186                              imgdepth);
01187                 }
01188                 else
01189                 {
01190                     phMemcpy(&(buf[(x + k * width)*imgdepth]),
01191                              tmp_color.array.v,
01192                              imgdepth);
01193                 }
01194             }
01195         } 
01196     }
01197  
01198     /* Reenable notify if it was disabled */
01199     if (reenable_notify)
01200     {
01201         this->m_image.enableNotify();
01202     }
01203    
01204     /* Swap the data back in */
01205     rc = this->m_image.swapData(&tw,&th,&tf,&buf,&ts);
01206     phCHECK_RC(rc,NULL,"this->m_image.swapData()");
01207    
01208     phRWUNLOCK(this->m_image,img_locked);
01209     phTHIS_UNLOCK(locked);
01210 
01211     phFree(scales);
01212 
01213     return phSUCCESS;
01214 error:
01215     phRWUNLOCK_ERROR(this->m_image,img_locked);
01216     phTHIS_ERROR_UNLOCK(locked);
01217 
01218     phFree(scales);
01219 
01220     return phFAIL;
01221 }
01222 
01223 /* ---------------------------------------------------------------------- */
01224 void phHistogramData::print_data()
01225 {
01226     phFUNCTION("phHistogramData::print_data")
01227     uint32_t i = 0;
01228     uint32_t j = 0;
01229     int locked = 0;
01230 
01231     /* Get the histogram information */
01232     const uint32_t nbins    = this->getBinCount();
01233     const uint32_t bin_step = this->getBinStep();
01234     /*const uint32_t bin_elems = nbins * bin_step;*/
01235     uint32_t *bins = NULL;
01236     
01237     /*const uint32_t columns = 4;*/
01238     const double binwidth = 256.0 / (double)nbins;
01239     
01240     phTHIS_LOOSE_LOCK(locked);
01241     
01242     /* print the values that the bins hold */
01243     printf("bin step:%lu\n",(unsigned long int)bin_step);
01244     printf("bin ranges:\n");
01245     for (i = 0; i < nbins; i++ )
01246     {
01247         printf("%3lu<",(unsigned long int)i);
01248         for (j = 0; j < bin_step; j++)
01249         {
01250             printf("%3lu",(unsigned long int)(i * bin_step) + j);
01251             if (j < (bin_step - 1)) 
01252                 printf(",");
01253         }
01254         printf(">");
01255 
01256         printf("[ %4.0f -> %4.0f ]",
01257                i*binwidth,
01258                ((i+1)*binwidth) - 1 );
01259         printf("\n");
01260     }    
01261     printf("\n");
01262    
01263     /* Print out the value of the bin elements */
01264     bins = this->getBinValArray();
01265     printf("bin value array:\n");
01266     for (i = 0; i < nbins; i++ )
01267     {
01268         printf( "%3lu< ", (unsigned long int)i );
01269         for (j = 0; j < bin_step; j++)
01270         {
01271             printf("%3lu",(unsigned long int)(i * bin_step) + j);
01272             if (j < (bin_step - 1)) 
01273                 printf(",");
01274         }
01275         printf(">[");
01276  
01277 
01278         for (j = 0; j < bin_step; j++ )
01279         {
01280             printf( "%6lu%s", (unsigned long int)bins[ (i * bin_step) + j ],
01281                     ((j == (bin_step - 1)) ? " " : ", ")  );
01282         }
01283         printf( "] ");
01284         printf("\n");
01285     }
01286     printf( "\n");
01287    
01288     /* Print out the #items in the each bin array*/
01289     bins = this->getBinCntArray();
01290     printf("bin count array:\n");
01291     for (i = 0; i < nbins; i++ )
01292     {
01293         printf( "%3lu< ", (unsigned long int)i );
01294         for (j = 0; j < bin_step; j++)
01295         {
01296             printf("%3lu",(unsigned long int)((i * bin_step) + j));
01297             if (j < (bin_step - 1)) 
01298                 printf(",");
01299         }
01300         printf(">[");
01301  
01302         for (j = 0; j < bin_step; j++ )
01303         {
01304             printf( "%6lu%s", (unsigned long int)bins[ (i * bin_step) + j ],
01305                     ((j == (bin_step - 1)) ? " " : ", ")  );
01306         }
01307         printf( "] ");
01308         printf("\n");
01309     }
01310     printf( "\n");
01311             
01312     /* Print the average of the values that were tallied in the bin array */
01313     bins = this->getBinAvgArray();
01314     printf("bin averages:\n");
01315     for (i = 0; i < nbins; i++ )
01316     {
01317         printf( "%3lu< ", (unsigned long int)i );
01318         for (j = 0; j < bin_step; j++)
01319         {
01320             printf("%3lu",(unsigned long int)((i * bin_step) + j));
01321             if (j < (bin_step - 1)) 
01322                 printf(",");
01323         }
01324         printf(">[");
01325         
01326         for (j = 0; j < bin_step; j++ )
01327         {
01328             printf("%6lu%s", (unsigned long int)bins[ (i * bin_step) + j ],
01329                    ((j == (bin_step - 1)) ? " " : ", ")  );
01330         }
01331         printf( "] ");
01332         printf("\n");
01333     }
01334     printf( "\n");
01335 
01336     this->print_stats();
01337     
01338     fflush(stdout);
01339     
01340     phTHIS_LOOSE_UNLOCK(locked);
01341 }
01342 
01343 /* ---------------------------------------------------------------------- */
01344 void phHistogramData::print_stats()
01345 {
01346     phFUNCTION("phHistogramData::print_stats")
01347     uint32_t j = 0;
01348     int locked = 0;
01349 
01350     /* Get the histogram information */
01351     /* const uint32_t nbins = this->getBinCount(); */
01352     const uint32_t bin_step = this->getBinStep();
01353     uint32_t *bins = NULL;
01354     
01355     phTHIS_LOOSE_LOCK(locked);
01356     
01357     /* print out the index of the bin with the most values */
01358     bins = this->getMaxBin();
01359     printf( "%16s:[","max bin index" );
01360     
01361     for (j = 0; j < bin_step; j++ )
01362     {
01363         printf("%4lu%s", (unsigned long int)bins[ j ],
01364                ((j == (bin_step - 1)) ? " " : ", ")
01365               );
01366     }
01367     printf( "] \n");
01368 
01369     /* print out the bin counts for the max bin */
01370     bins = this->getMaxArray();
01371     printf( "%16s:[","max counts" );
01372     
01373     for (j = 0; j < bin_step; j++ )
01374     {
01375         printf("%4lu%s", (unsigned long int)bins[ j ],
01376                 ((j == (bin_step - 1)) ? " " : ", ")
01377                 );
01378     }
01379     printf( "] \n");
01380 
01381     /* Print out the average for the values tallied into the bins */
01382     bins = this->getMaxAvgArray();
01383     printf( "%16s:[","max averages" );
01384     
01385     for (j = 0; j < bin_step; j++ )
01386     {
01387         printf("%4lu%s", (unsigned long int)bins[ j ],
01388                ((j == (bin_step - 1)) ? " " : ", ")
01389                );
01390     }
01391     printf( "] \n");
01392 
01393     printf("%16s:[%4u, %4u, %4u,%4u ]\n",
01394               "maxbin_color", 
01395               m_maxbin_color.array.v[0],
01396               m_maxbin_color.array.v[1],
01397               m_maxbin_color.array.v[2],
01398               m_maxbin_color.array.v[3] );
01399     printf("%16s:[%4u, %4u, %4u, %4u ]\n",
01400            "maxbin_threshold",
01401            m_maxbin_threshold.array.v[0],
01402            m_maxbin_threshold.array.v[1],
01403            m_maxbin_threshold.array.v[2],
01404            m_maxbin_threshold.array.v[3] );
01405     printf("%16s:[%4u, %4u, %4u, %4u ]\n",
01406            "threshold",
01407            m_threshold.array.v[0],
01408            m_threshold.array.v[1],
01409            m_threshold.array.v[2],
01410            m_threshold.array.v[3] );
01411     printf("%16s:[%4u, %4u, %4u, %4u ]\n",
01412            "color",
01413            m_color.array.v[0],
01414            m_color.array.v[1],
01415            m_color.array.v[2],
01416            m_color.array.v[3] );
01417     
01418     printf("\n");
01419     fflush(stdout);
01420     
01421     phTHIS_LOOSE_UNLOCK(locked);
01422 }
01423 
01424 /* ---------------------------------------------------------------------- */
01425 phImage *phHistogramData::getImage()
01426 { 
01427     return &(this->m_image);
01428 }
01429 
01430 /* ---------------------------------------------------------------------- */
01431 int phHistogramData::save(const char *filename, int overwrite )
01432 {
01433     phFUNCTION("phHistogramData::save")
01434     FILE        *fp     = NULL;
01435     uint32_t    i       = 0;
01436     uint32_t    j       = 0;
01437     int         locked  = 0;
01438     uint32_t    type    = phHISTFILE_ALL;
01439 
01440 #ifndef __ADSPBLACKFIN__
01441     phTHIS_LOCK(locked);
01442 
01443     if (filename == NULL) return phFAIL;
01444 
01445     /* CHECK IF THE FILE EXISTS ALREADY */
01446     fp = fopen(filename,"rt");
01447     if ((fp != NULL) && (overwrite == 0))
01448     {
01449         phCHECK_RC(-1,NULL,"overwrite == 0 && file %s exists\n",
01450                    filename);
01451     }
01452     else if (fp != NULL)
01453     {
01454         fclose(fp);
01455         fp = NULL;
01456     }
01457 
01458     /* open the output file */
01459     fp = fopen(filename, "wt");
01460     phCHECK_PTR(fp,"fopen","fopen(%s,\"wt\")",filename);
01461 
01462     rc = ph_file_lock(fp);
01463     phPRINT_RC(rc,"ph_file_lock","ph_file_lock(%p)",fp);
01464 
01465     /* print out the format of the histogram info */
01466     /* phHISTFILE_ALL: all the info */
01467     if (type == phHISTFILE_ALL)
01468     {
01469         rc = fprintf(fp,"phHISTFILE_ALL\n");
01470         if (rc == EOF) goto success;
01471     }
01472     /* phHISTFILE_BASIC (default): just the CNT and VAL bins */
01473     else
01474     {
01475         rc = fprintf(fp,"phHISTFILE_BASIC\n");
01476         if (rc == EOF) goto success;
01477     }
01478 
01479     /* print the size of the histogram */
01480     /* <bincount> <binstep> <binelems> */
01481     rc = fprintf(fp,"%u %u %u\n",this->m_binCount,this->m_binStep,this->m_binElems);
01482     if (rc == EOF) goto success;
01483     
01484     /* print out the CNT array */
01485     for (i = 0; i < this->m_binElems; i++ )
01486     {
01487         rc = fprintf(fp,"%u ", this->m_binCnt[i]);
01488         if (rc == EOF) goto success;
01489     }
01490     rc = fprintf(fp,"\n");
01491     if (rc == EOF) goto success;
01492 
01493     /* print out the VAL array */
01494     for (i = 0; i < this->m_binElems; i++ )
01495     {
01496         rc = fprintf(fp,"%u ", this->m_binVal[i]);
01497         if (rc == EOF) goto success;
01498     }
01499     rc = fprintf(fp,"\n");
01500     if (rc == EOF) goto success;
01501     
01502     /* if printing ALL the info */
01503     if (type == phHISTFILE_ALL)
01504     {
01505         /* print out the: */
01506         /* - binAvg array */
01507         for (i = 0; i < this->m_binElems; i++ )
01508         {
01509             fprintf(fp,"%u ",this->m_binAvg[i]);
01510             if (rc == EOF) goto success;
01511         }
01512         rc = fprintf(fp,"\n");
01513         if (rc == EOF) goto success;
01514         
01515         /* - maxBin array */
01516         for (i = 0; i < this->m_binStep; i++ )
01517         {
01518             fprintf(fp,"%u ",this->m_maxBin[i]);
01519             if (rc == EOF) goto success;
01520         }
01521         rc = fprintf(fp,"\n");
01522         if (rc == EOF) goto success;
01523         
01524         /* - maxCnt array */
01525         for (i = 0; i < this->m_binStep; i++ )
01526         {
01527             fprintf(fp,"%u ",this->m_maxCnt[i]);
01528             if (rc == EOF) goto success;
01529         }
01530         rc = fprintf(fp,"\n");
01531         if (rc == EOF) goto success;
01532         
01533         /* - maxAvg array */
01534         for (i = 0; i < this->m_binStep; i++ )
01535         {
01536             fprintf(fp,"%u ",this->m_maxAvg[i]);
01537             if (rc == EOF) goto success;
01538         }
01539         rc = fprintf(fp,"\n");
01540         if (rc == EOF) goto success;
01541         
01542         /* - color */
01543         rc = phColorPrint(fileno(fp),this->m_color);
01544         phPRINT_RC(rc,NULL,"phColorPrint");
01545 
01546         /* - threshold */
01547         rc = phColorPrint(fileno(fp),this->m_threshold);
01548         phPRINT_RC(rc,NULL,"phColorPrint");
01549 
01550         /* - maxbin_color */
01551         rc = phColorPrint(fileno(fp),this->m_maxbin_color);
01552         phPRINT_RC(rc,NULL,"phColorPrint");
01553 
01554         /* - maxbin_threshold */
01555         rc = phColorPrint(fileno(fp),this->m_maxbin_threshold);
01556         phPRINT_RC(rc,NULL,"phColorPrint");
01557 
01558         /* - image_height */
01559         rc = fprintf(fp,"%u",this->m_image_height);
01560         if (rc == EOF) goto success;
01561 
01562         rc = fprintf(fp,"\n");
01563         if (rc == EOF) goto success;
01564     }
01565     
01566     /* close the file */
01567 success:
01568     rc = ph_file_unlock(fp);
01569     phPRINT_RC(rc,"ph_file_unlock","ph_file_unlock(%p)",fp);
01570 
01571     if (fp != NULL)
01572     {
01573         fclose(fp);
01574         fp = NULL;
01575     }
01576 
01577     phTHIS_UNLOCK(locked);
01578 
01579     return phSUCCESS;
01580 error:
01581     if (fp != NULL)
01582     {
01583         fclose(fp);
01584     }
01585     phTHIS_ERROR_UNLOCK(locked);
01586 
01587 #endif
01588     return phFAIL;
01589 
01590 }
01591 
01592 /* ---------------------------------------------------------------------- */
01593 int phHistogramData::load(const char *filename)
01594 {
01595     phFUNCTION("phHistogramData::load")
01596     FILE        *fp     = NULL;
01597     uint32_t    i       = 0;
01598     uint32_t    j       = 0;
01599     int         locked  = 0;
01600     uintmax_t   length  = 0;
01601     uint32_t    type    = phHISTFILE_ALL;
01602     char        *strtype= NULL;
01603     phColor     *colors = NULL;
01604 
01605 #ifndef __ADSPBLACKFIN__
01606     phTHIS_LOCK(locked);
01607 
01608     if (filename == NULL) return phFAIL;
01609 
01610     /* open the output file */
01611     fp = fopen(filename, "rt");
01612     phCHECK_PTR(fp,"fopen","fopen(%s,\"rt\")",filename);
01613 
01614     rc = ph_file_lock(fp);
01615     phPRINT_RC(rc,"ph_file_lock","ph_file_lock(%p)",fp);
01616 
01617     strtype = (char *)phCalloc(255,sizeof(char));
01618     phCHECK_PTR(strtype,"phCalloc","phCalloc failed.");
01619 
01620     /* read in the format of the histogram info */
01621     rc = fscanf( fp, "%s\n", strtype );
01622     if (rc == EOF) goto success;
01623 
01624     /* get the length of the string and overwrite the EOL with the
01625      * NULLBYTE */
01626     length = strlen(strtype);
01627     strtype[length-2]='\0';
01628     length--;
01629     
01630     /* phHISTFILE_ALL: all the info */
01631     if (strcmp(strtype,"phHISTFILE_ALL") == 0)
01632     {
01633         type = phHISTFILE_ALL;
01634     }
01635     /* phHISTFILE_BASIC (default): just the CNT and VAL bins */
01636     else if (strcmp(strtype,"phHISTFILE_BASIC") == 0)
01637     {
01638         type = phHISTFILE_BASIC;
01639     }
01640     else
01641     {
01642         phCHECK_RC(-1,NULL,
01643                     "Invalid histogram file. Couldn't parse histfile type");
01644     }
01645 
01646     /* print the size of the histogram */
01647     /* <bincount> <binstep> <binelems> */
01648     rc = fscanf(fp,"%u %u %u\n",&(this->m_binCount),&(this->m_binStep),
01649                 &(this->m_binElems));
01650     if (rc == EOF) goto success;
01651     
01652     phDALLOC_RESIZE(this->m_binVal, this->m_binVal_size, 
01653                     this->m_binElems, uint32_t );
01654     phDALLOC_RESIZE(this->m_binCnt, this->m_binCnt_size,
01655                     this->m_binElems, uint32_t );
01656     phDALLOC_RESIZE(this->m_binAvg, this->m_binAvg_size,
01657                     this->m_binElems, uint32_t );
01658     
01659     /* print out the CNT array */
01660     for (i = 0; i < this->m_binElems; i++ )
01661     {
01662         rc = fscanf(fp,"%u ", &(this->m_binCnt[i]));
01663         if (rc == EOF) goto success;
01664     }
01665     rc = fprintf(fp,"\n");
01666     if (rc == EOF) goto success;
01667 
01668     /* print out the VAL array */
01669     for (i = 0; i < this->m_binElems; i++ )
01670     {
01671         rc = fscanf(fp,"%u ", &(this->m_binVal[i]));
01672         if (rc == EOF) goto success;
01673     }
01674     rc = fscanf(fp,"\n");
01675     if (rc == EOF) goto success;
01676     
01677     /* if printing ALL the info */
01678     if (type != phHISTFILE_ALL)
01679     {
01680         rc = this->updateFromBins();
01681         phCHECK_RC(rc,NULL,"this->updateFromBins");
01682     }
01683     else
01684     {
01685         phDALLOC_RESIZE(this->m_maxAvg, this->m_maxAvg_size, 
01686                         this->m_binStep, uint32_t);
01687         phDALLOC_RESIZE(this->m_maxCnt, this->m_maxCnt_size, 
01688                         this->m_binStep, uint32_t);
01689         phDALLOC_RESIZE(this->m_maxBin, this->m_maxBin_size, 
01690                         this->m_binStep, uint32_t);
01691         
01692         /* print out the: */
01693         /* - binAvg array */
01694         for (i = 0; i < this->m_binElems; i++ )
01695         {
01696             fscanf(fp,"%u ",&(this->m_binAvg[i]));
01697             if (rc == EOF) goto success;
01698         }
01699         rc = fscanf(fp,"\n");
01700         if (rc == EOF) goto success;
01701         
01702         /* - maxBin array */
01703         for (i = 0; i < this->m_binStep; i++ )
01704         {
01705             fscanf(fp,"%u ",&(this->m_maxBin[i]));
01706             if (rc == EOF) goto success;
01707         }
01708         rc = fscanf(fp,"\n");
01709         if (rc == EOF) goto success;
01710         
01711         /* - maxCnt array */
01712         for (i = 0; i < this->m_binStep; i++ )
01713         {
01714             fscanf(fp,"%u ",&(this->m_maxCnt[i]));
01715             if (rc == EOF) goto success;
01716         }
01717         rc = fscanf(fp,"\n");
01718         if (rc == EOF) goto success;
01719         
01720         /* - maxAvg array */
01721         for (i = 0; i < this->m_binStep; i++ )
01722         {
01723             fscanf(fp,"%u ",&(this->m_maxAvg[i]));
01724             if (rc == EOF) goto success;
01725         }
01726         rc = fscanf(fp,"\n");
01727         if (rc == EOF) goto success;
01728        
01729         rc = phColorRead(fileno(fp),4,NULL,&colors);
01730         phPRINT_RC(rc,NULL,"phColorRead");
01731         
01732         /* - color */
01733         this->m_color               = colors[0];
01734         /* - threshold */
01735         this->m_threshold           = colors[1];
01736         /* - maxbin_color */
01737         this->m_maxbin_color        = colors[2];
01738         /* - maxbin_threshold */
01739         this->m_maxbin_threshold    = colors[3];
01740 
01741         phFree(colors);
01742 
01743         /* - image_height */
01744         rc = fscanf(fp,"%u",this->m_image_height);
01745         if (rc == EOF) goto success;
01746 
01747         rc = fscanf(fp,"\n");
01748         if (rc == EOF) goto success;
01749     }
01750     
01751     /* close the file */
01752 success:
01753     rc = ph_file_unlock(fp);
01754     phPRINT_RC(rc,"ph_file_unlock","ph_file_unlock(%p)",fp);
01755 
01756     fclose(fp);
01757     fp = NULL;
01758 
01759     phFree(strtype);
01760     phTHIS_UNLOCK(locked);
01761 
01762     return phSUCCESS;
01763 error:
01764     if (fp != NULL)
01765     {
01766         fclose(fp);
01767     }
01768     phFree(strtype);
01769     phTHIS_ERROR_UNLOCK(locked);
01770 
01771 #endif
01772     return phFAIL;
01773 
01774 }




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:11 2007 for phission by  doxygen 1.4.4