static void splitbox(Colorbox* ptr, const int* histogram, const HashHistogram* psHashHistogram, int nCLevels, Colorbox **pfreeboxes, Colorbox **pusedboxes, GByte* pabyRedBand, GByte* pabyGreenBand, GByte* pabyBlueBand, int nPixels) { int hist2[256]; int first=0, last=0; Colorbox *new_cb; const int *iptr; int *histp; int i, j; int ir,ig,ib; int sum, sum1, sum2; enum { RED, GREEN, BLUE } axis; /* * See which axis is the largest, do a histogram along that * axis. Split at median point. Contract both new boxes to * fit points and return */ i = ptr->rmax - ptr->rmin; if (i >= ptr->gmax - ptr->gmin && i >= ptr->bmax - ptr->bmin) axis = RED; else if (ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin) axis = GREEN; else axis = BLUE; /* get histogram along longest axis */ int nIters = (ptr->rmax - ptr->rmin + 1) * (ptr->gmax - ptr->gmin + 1) * (ptr->bmax - ptr->bmin + 1); //printf("nIters = %d\n", nIters); switch (axis) { case RED: { if( nPixels != 0 && nIters > nPixels ) { memset(hist2, 0, sizeof(hist2)); const int rmin = ptr->rmin, rmax = ptr->rmax, gmin = ptr->gmin, gmax = ptr->gmax, bmin = ptr->bmin, bmax = ptr->bmax; for(int i=0; i<nPixels; i++) { int iR = pabyRedBand[i]; int iG = pabyGreenBand[i]; int iB = pabyBlueBand[i]; if( iR >= rmin && iR <= rmax && iG >= gmin && iG <= gmax && iB >= bmin && iB <= bmax ) { hist2[iR] ++; } } } else if( psHashHistogram ) { histp = &hist2[ptr->rmin]; for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { *histp = 0; for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) { *histp += FindColorCount(psHashHistogram, MAKE_COLOR_CODE(ir, ig, ib)); } } histp++; } } else { histp = &hist2[ptr->rmin]; for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { *histp = 0; for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { iptr = &HISTOGRAM(histogram,nCLevels,ir,ig,ptr->bmin); for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) *histp += *iptr++; } histp++; } } first = ptr->rmin; last = ptr->rmax; break; } case GREEN: { if( nPixels != 0 && nIters > nPixels ) { memset(hist2, 0, sizeof(hist2)); const int rmin = ptr->rmin, rmax = ptr->rmax, gmin = ptr->gmin, gmax = ptr->gmax, bmin = ptr->bmin, bmax = ptr->bmax; for(int i=0; i<nPixels; i++) { int iR = pabyRedBand[i]; int iG = pabyGreenBand[i]; int iB = pabyBlueBand[i]; if( iR >= rmin && iR <= rmax && iG >= gmin && iG <= gmax && iB >= bmin && iB <= bmax ) { hist2[iG] ++; } } } else if( psHashHistogram ) { histp = &hist2[ptr->gmin]; for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { *histp = 0; for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) { *histp += FindColorCount(psHashHistogram, MAKE_COLOR_CODE(ir, ig, ib)); } } histp++; } } else { histp = &hist2[ptr->gmin]; for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { *histp = 0; for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { iptr = &HISTOGRAM(histogram,nCLevels,ir,ig,ptr->bmin); for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) *histp += *iptr++; } histp++; } } first = ptr->gmin; last = ptr->gmax; break; } case BLUE: { if( nPixels != 0 && nIters > nPixels ) { memset(hist2, 0, sizeof(hist2)); const int rmin = ptr->rmin, rmax = ptr->rmax, gmin = ptr->gmin, gmax = ptr->gmax, bmin = ptr->bmin, bmax = ptr->bmax; for(int i=0; i<nPixels; i++) { int iR = pabyRedBand[i]; int iG = pabyGreenBand[i]; int iB = pabyBlueBand[i]; if( iR >= rmin && iR <= rmax && iG >= gmin && iG <= gmax && iB >= bmin && iB <= bmax ) { hist2[iB] ++; } } } else if( psHashHistogram ) { histp = &hist2[ptr->bmin]; for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) { *histp = 0; for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { *histp += FindColorCount(psHashHistogram, MAKE_COLOR_CODE(ir, ig, ib)); } } histp++; } } else { histp = &hist2[ptr->bmin]; for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) { *histp = 0; for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { iptr = &HISTOGRAM(histogram,nCLevels,ir,ptr->gmin,ib); for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { *histp += *iptr; iptr += nCLevels; } } histp++; } } first = ptr->bmin; last = ptr->bmax; break; } } /* find median point */ sum2 = ptr->total / 2; histp = &hist2[first]; sum = 0; for (i = first; i <= last && (sum += *histp++) < sum2; ++i) ; if (i == first) i++; /* Create new box, re-allocate points */ new_cb = *pfreeboxes; *pfreeboxes = new_cb->next; if (*pfreeboxes) (*pfreeboxes)->prev = NULL; if (*pusedboxes) (*pusedboxes)->prev = new_cb; new_cb->next = *pusedboxes; *pusedboxes = new_cb; histp = &hist2[first]; for (sum1 = 0, j = first; j < i; j++) sum1 += *histp++; for (sum2 = 0, j = i; j <= last; j++) sum2 += *histp++; new_cb->total = sum1; ptr->total = sum2; new_cb->rmin = ptr->rmin; new_cb->rmax = ptr->rmax; new_cb->gmin = ptr->gmin; new_cb->gmax = ptr->gmax; new_cb->bmin = ptr->bmin; new_cb->bmax = ptr->bmax; switch (axis) { case RED: new_cb->rmax = i-1; ptr->rmin = i; break; case GREEN: new_cb->gmax = i-1; ptr->gmin = i; break; case BLUE: new_cb->bmax = i-1; ptr->bmin = i; break; } if( nPixels != 0 && (new_cb->rmax - new_cb->rmin + 1) * (new_cb->gmax - new_cb->gmin + 1) * (new_cb->bmax - new_cb->bmin + 1) > nPixels ) { shrinkboxFromBand(new_cb, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); } else if( psHashHistogram != NULL ) { shrinkboxFromHashHistogram(new_cb, psHashHistogram); } else { shrinkbox(new_cb, histogram, nCLevels); } if( nPixels != 0 && (ptr->rmax - ptr->rmin + 1) * (ptr->gmax - ptr->gmin + 1) * (ptr->bmax - ptr->bmin + 1) > nPixels ) { shrinkboxFromBand(ptr, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); } else if( psHashHistogram != NULL ) { shrinkboxFromHashHistogram(ptr, psHashHistogram); } else { shrinkbox(ptr, histogram, nCLevels); } }
template<class T> static void splitbox(Colorbox* ptr, const T* histogram, const HashHistogram* psHashHistogram, int nCLevels, Colorbox **pfreeboxes, Colorbox **pusedboxes, GByte* pabyRedBand, GByte* pabyGreenBand, GByte* pabyBlueBand, T nPixels) { T hist2[256] = {}; int first = 0; int last = 0; enum { RED, GREEN, BLUE } axis; // See which axis is the largest, do a histogram along that axis. Split at // median point. Contract both new boxes to fit points and return. { int i = ptr->rmax - ptr->rmin; if( i >= ptr->gmax - ptr->gmin && i >= ptr->bmax - ptr->bmin ) axis = RED; else if( ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin ) axis = GREEN; else axis = BLUE; } // Get histogram along longest axis. const GUInt32 nIters = (ptr->rmax - ptr->rmin + 1) * (ptr->gmax - ptr->gmin + 1) * (ptr->bmax - ptr->bmin + 1); switch( axis ) { case RED: { if( nPixels != 0 && nIters > nPixels ) { const int rmin = ptr->rmin; const int rmax = ptr->rmax; const int gmin = ptr->gmin; const int gmax = ptr->gmax; const int bmin = ptr->bmin; const int bmax = ptr->bmax; for( T iPixel = 0; iPixel < nPixels; iPixel++ ) { int iR = pabyRedBand[iPixel]; int iG = pabyGreenBand[iPixel]; int iB = pabyBlueBand[iPixel]; if( iR >= rmin && iR <= rmax && iG >= gmin && iG <= gmax && iB >= bmin && iB <= bmax ) { hist2[iR]++; } } } else if( psHashHistogram ) { T *histp = &hist2[ptr->rmin]; for( int ir = ptr->rmin; ir <= ptr->rmax; ++ir ) { *histp = 0; for( int ig = ptr->gmin; ig <= ptr->gmax; ++ig ) { for( int ib = ptr->bmin; ib <= ptr->bmax; ++ib ) { *histp += FindColorCount(psHashHistogram, MAKE_COLOR_CODE(ir, ig, ib)); } } histp++; } } else { T *histp = &hist2[ptr->rmin]; for( int ir = ptr->rmin; ir <= ptr->rmax; ++ir ) { *histp = 0; for( int ig = ptr->gmin; ig <= ptr->gmax; ++ig ) { const T *iptr = HISTOGRAM(histogram, nCLevels, ir, ig, ptr->bmin); for( int ib = ptr->bmin; ib <= ptr->bmax; ++ib ) *histp += *iptr++; } histp++; } } first = ptr->rmin; last = ptr->rmax; break; } case GREEN: { if( nPixels != 0 && nIters > nPixels ) { const int rmin = ptr->rmin; const int rmax = ptr->rmax; const int gmin = ptr->gmin; const int gmax = ptr->gmax; const int bmin = ptr->bmin; const int bmax = ptr->bmax; for( T iPixel = 0; iPixel < nPixels; iPixel++ ) { const int iR = pabyRedBand[iPixel]; const int iG = pabyGreenBand[iPixel]; const int iB = pabyBlueBand[iPixel]; if( iR >= rmin && iR <= rmax && iG >= gmin && iG <= gmax && iB >= bmin && iB <= bmax ) { hist2[iG]++; } } } else if( psHashHistogram ) { T *histp = &hist2[ptr->gmin]; for( int ig = ptr->gmin; ig <= ptr->gmax; ++ig ) { *histp = 0; for( int ir = ptr->rmin; ir <= ptr->rmax; ++ir ) { for( int ib = ptr->bmin; ib <= ptr->bmax; ++ib ) { *histp += FindColorCount(psHashHistogram, MAKE_COLOR_CODE(ir, ig, ib)); } } histp++; } } else { T *histp = &hist2[ptr->gmin]; for( int ig = ptr->gmin; ig <= ptr->gmax; ++ig ) { *histp = 0; for( int ir = ptr->rmin; ir <= ptr->rmax; ++ir ) { const T *iptr = HISTOGRAM(histogram, nCLevels, ir, ig, ptr->bmin); for( int ib = ptr->bmin; ib <= ptr->bmax; ++ib ) *histp += *iptr++; } histp++; } } first = ptr->gmin; last = ptr->gmax; break; } case BLUE: { if( nPixels != 0 && nIters > nPixels ) { const int rmin = ptr->rmin; const int rmax = ptr->rmax; const int gmin = ptr->gmin; const int gmax = ptr->gmax; const int bmin = ptr->bmin; const int bmax = ptr->bmax; for( T iPixel = 0; iPixel < nPixels; iPixel++ ) { const int iR = pabyRedBand[iPixel]; const int iG = pabyGreenBand[iPixel]; const int iB = pabyBlueBand[iPixel]; if( iR >= rmin && iR <= rmax && iG >= gmin && iG <= gmax && iB >= bmin && iB <= bmax ) { hist2[iB]++; } } } else if( psHashHistogram ) { T *histp = &hist2[ptr->bmin]; for( int ib = ptr->bmin; ib <= ptr->bmax; ++ib ) { *histp = 0; for( int ir = ptr->rmin; ir <= ptr->rmax; ++ir ) { for( int ig = ptr->gmin; ig <= ptr->gmax; ++ig ) { *histp += FindColorCount(psHashHistogram, MAKE_COLOR_CODE(ir, ig, ib)); } } histp++; } } else { T *histp = &hist2[ptr->bmin]; for( int ib = ptr->bmin; ib <= ptr->bmax; ++ib ) { *histp = 0; for( int ir = ptr->rmin; ir <= ptr->rmax; ++ir ) { const T *iptr = HISTOGRAM(histogram, nCLevels, ir, ptr->gmin, ib); for( int ig = ptr->gmin; ig <= ptr->gmax; ++ig ) { *histp += *iptr; iptr += nCLevels; } } histp++; } } first = ptr->bmin; last = ptr->bmax; break; } } // Find median point. T *histp = &hist2[first]; int i = first; // TODO(schwehr): Rename i. { T sum = 0; T sum2 = static_cast<T>(ptr->total / 2); for( ; i <= last && (sum += *histp++) < sum2; ++i ) {} } if( i == first ) i++; // Create new box, re-allocate points. Colorbox *new_cb = *pfreeboxes; *pfreeboxes = new_cb->next; if( *pfreeboxes ) (*pfreeboxes)->prev = NULL; if( *pusedboxes ) (*pusedboxes)->prev = new_cb; new_cb->next = *pusedboxes; *pusedboxes = new_cb; histp = &hist2[first]; { T sum1 = 0; for( int j = first; j < i; j++ ) sum1 += *histp++; T sum2 = 0; for( int j = i; j <= last; j++ ) sum2 += *histp++; new_cb->total = sum1; ptr->total = sum2; } new_cb->rmin = ptr->rmin; new_cb->rmax = ptr->rmax; new_cb->gmin = ptr->gmin; new_cb->gmax = ptr->gmax; new_cb->bmin = ptr->bmin; new_cb->bmax = ptr->bmax; switch( axis ) { case RED: new_cb->rmax = i - 1; ptr->rmin = i; break; case GREEN: new_cb->gmax = i - 1; ptr->gmin = i; break; case BLUE: new_cb->bmax = i - 1; ptr->bmin = i; break; } if( nPixels != 0 && static_cast<T>(new_cb->rmax - new_cb->rmin + 1) * static_cast<T>(new_cb->gmax - new_cb->gmin + 1) * static_cast<T>(new_cb->bmax - new_cb->bmin + 1) > nPixels ) { shrinkboxFromBand(new_cb, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); } else if( psHashHistogram != NULL ) { shrinkboxFromHashHistogram(new_cb, psHashHistogram); } else { shrinkbox(new_cb, histogram, nCLevels); } if( nPixels != 0 && static_cast<T>(ptr->rmax - ptr->rmin + 1) * static_cast<T>(ptr->gmax - ptr->gmin + 1) * static_cast<T>(ptr->bmax - ptr->bmin + 1) > nPixels ) { shrinkboxFromBand(ptr, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); } else if( psHashHistogram != NULL ) { shrinkboxFromHashHistogram(ptr, psHashHistogram); } else { shrinkbox(ptr, histogram, nCLevels); } }