Exemple #1
0
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);
    }
}
Exemple #2
0
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);
    }
}