<commit_before>/*
 *  usimage.cpp
 *  PHD Guiding
 *
 *  Created by <NAME>.
 *  Copyright (c) 2006-2010 <NAME>.
 *  All rights reserved.
 *
 *  This source code is distributed under the following "BSD" license
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *    Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *    Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *    Neither the name of <NAME>, Stark Labs nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "phd.h"
#include "image_math.h"

bool usImage::Init(int xsize, int ysize) {
// Allocates space for image and sets params up
// returns true on error
    if (ImageData) {
        delete[] ImageData;
        ImageData = NULL;
    }
    NPixels = xsize * ysize;
    Size = wxSize(xsize,ysize);
    Subframe = wxRect(0, 0, 0, 0);
    Min = Max = 0;
    if (NPixels) {
        ImageData = new unsigned short[NPixels];
        if (!ImageData) return true;
    }
    return false;
}

void usImage::CalcStats() {
    int i, d;
    unsigned short *ptr, *tmpdata;

    if ((!ImageData) || (!NPixels))
        return;

    tmpdata = new unsigned short[NPixels];

    Min = 65535; Max = 0;
    FiltMin = 65535; FiltMax = 0;

    if (Subframe.width <= 0 || Subframe.height <= 0)
    {
        for (i=0, ptr=ImageData; i<NPixels; i++, ptr++) {
            d = (int) ( *ptr);
            if (d < Min) Min = d;
            if (d > Max) Max = d;
            tmpdata[i]=d;
        }

        Median3(tmpdata,Size.GetWidth(),Size.GetHeight());
        for (i=0, ptr=tmpdata; i<NPixels; i++, ptr++) {
            d = (int) ( *ptr);
            if (d < FiltMin) FiltMin = d;
            if (d > FiltMax) FiltMax = d;
        }
    }
    else
    {  // Subframe
        int x, y;
        i=0;
        for (y=0; y<Subframe.height; y++) {
            ptr = ImageData + Subframe.x + (Subframe.y + y)*Size.GetWidth();
            for (x=0; x<Subframe.width; x++, ptr++, i++) {
               d = (int) ( *ptr);
               if (d < Min) Min = d;
               if (d > Max) Max = d;
               tmpdata[i]=d;
           }
        }

        Median3(tmpdata, Subframe.width, Subframe.height);
        for (i=0, ptr=tmpdata; i<(Subframe.width*Subframe.height); i++, ptr++) {
            d = (int) ( *ptr);
            if (d < FiltMin) FiltMin = d;
            if (d > FiltMax) FiltMax = d;
        }
    }

    delete [] tmpdata;
}

bool usImage::Clean() {

    return false;
}

bool usImage::CopyToImage(wxImage **rawimg, int blevel, int wlevel, double power) {
    wxImage *img;
    unsigned char *ImgPtr;
    unsigned short *RawPtr;
    int i;
    float d;

//  Binsize = 1;
    img = *rawimg;
    if ((!img->Ok()) || (img->GetWidth() != Size.GetWidth()) || (img->GetHeight() != Size.GetHeight()) ) {  // can't reuse bitmap
        if (img->Ok()) {
            delete img;  // Clear out current image if it exists
            img = (wxImage *) NULL;
        }
        img = new wxImage(Size.GetWidth(), Size.GetHeight(), false);
    }
    ImgPtr = img->GetData();
    RawPtr = ImageData;
//  s_factor = (((float) Max - (float) Min) / 255.0);

    float range = (float) (wlevel - blevel);

    if ((power == 1.0) || (range == 0.0)) {
        range = wlevel;  // Go 0-max
        for (i=0; i<NPixels; i++, RawPtr++ ) {
            d = ((float) (*RawPtr) / range) * 255.0;
            if (d < 0.0) d = 0.0;
            else if (d > 255.0) d = 255.0;
            *ImgPtr = (unsigned char) d;
            ImgPtr++;
            *ImgPtr = (unsigned char) d;
            ImgPtr++;
            *ImgPtr = (unsigned char) d;
            ImgPtr++;

        }
    }
    else {
        for (i=0; i<NPixels; i++, RawPtr++ ) {
            d = ((float) (*RawPtr) - (float) blevel) / range;
            if (d < 0.0) d= 0.0;
            else if (d > 1.0) d = 1.0;
            d = pow(d, (float) power) * 255.0;
            *ImgPtr = (unsigned char) d;
            ImgPtr++;
            *ImgPtr = (unsigned char) d;
            ImgPtr++;
            *ImgPtr = (unsigned char) d;
            ImgPtr++;

        }
    }
    *rawimg = img;
    return false;
}

bool usImage::BinnedCopyToImage(wxImage **rawimg, int blevel, int wlevel, double power) {
    wxImage *img;
    unsigned char *ImgPtr;
    unsigned short *RawPtr;
    int x,y;
    float d;
    //, s_factor;
    int full_xsize, full_ysize;
    int use_xsize, use_ysize;
<commit_msg>performance improvement to usImage::CopyToImage  - only do stretch computation on pixels inside the hi/lo range. this is a big win when subframes are being used since in that case almost all the pixels are black and need not be stretched.  (hot spot found with cpu profiling) <commit_after>/*
 *  usimage.cpp
 *  PHD Guiding
 *
 *  Created by <NAME>.
 *  Copyright (c) 2006-2010 <NAME>.
 *  All rights reserved.
 *
 *  This source code is distributed under the following "BSD" license
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *    Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *    Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *    Neither the name of Craig Stark, Stark Labs nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "phd.h"
#include "image_math.h"

bool usImage::Init(int xsize, int ysize) {
// Allocates space for image and sets params up
// returns true on error
    if (ImageData) {
        delete[] ImageData;
        ImageData = NULL;
    }
    NPixels = xsize * ysize;
    Size = wxSize(xsize,ysize);
    Subframe = wxRect(0, 0, 0, 0);
    Min = Max = 0;
    if (NPixels) {
        ImageData = new unsigned short[NPixels];
        if (!ImageData) return true;
    }
    return false;
}

void usImage::CalcStats() {
    int i, d;
    unsigned short *ptr, *tmpdata;

    if ((!ImageData) || (!NPixels))
        return;

    tmpdata = new unsigned short[NPixels];

    Min = 65535; Max = 0;
    FiltMin = 65535; FiltMax = 0;

    if (Subframe.width <= 0 || Subframe.height <= 0)
    {
        for (i=0, ptr=ImageData; i<NPixels; i++, ptr++) {
            d = (int) ( *ptr);
            if (d < Min) Min = d;
            if (d > Max) Max = d;
            tmpdata[i]=d;
        }

        Median3(tmpdata,Size.GetWidth(),Size.GetHeight());
        for (i=0, ptr=tmpdata; i<NPixels; i++, ptr++) {
            d = (int) ( *ptr);
            if (d < FiltMin) FiltMin = d;
            if (d > FiltMax) FiltMax = d;
        }
    }
    else
    {  // Subframe
        int x, y;
        i=0;
        for (y=0; y<Subframe.height; y++) {
            ptr = ImageData + Subframe.x + (Subframe.y + y)*Size.GetWidth();
            for (x=0; x<Subframe.width; x++, ptr++, i++) {
               d = (int) ( *ptr);
               if (d < Min) Min = d;
               if (d > Max) Max = d;
               tmpdata[i]=d;
           }
        }

        Median3(tmpdata, Subframe.width, Subframe.height);
        for (i=0, ptr=tmpdata; i<(Subframe.width*Subframe.height); i++, ptr++) {
            d = (int) ( *ptr);
            if (d < FiltMin) FiltMin = d;
            if (d > FiltMax) FiltMax = d;
        }
    }

    delete [] tmpdata;
}

bool usImage::Clean() {

    return false;
}

bool usImage::CopyToImage(wxImage **rawimg, int blevel, int wlevel, double power)
{
    wxImage *img = *rawimg;

    if (!img->Ok() || (img->GetWidth() != Size.GetWidth()) || (img->GetHeight() != Size.GetHeight()) ) // can't reuse bitmap
    {
        if (img->Ok())
        {
            delete img;  // Clear out current image if it exists
            img = (wxImage *) NULL;
        }
        img = new wxImage(Size.GetWidth(), Size.GetHeight(), false);
    }

    unsigned char *ImgPtr = img->GetData();
    unsigned short *RawPtr = ImageData;

    if (power == 1.0 || blevel >= wlevel)
    {
        float range = wlevel;  // Go 0-max
        for (int i = 0; i < NPixels; i++, RawPtr++)
        {
            float d;
            if (*RawPtr >= wlevel)
                d = 255.0;
            else
                d = ((float) (*RawPtr) / range) * 255.0;

            *ImgPtr++ = (unsigned char) d;
            *ImgPtr++ = (unsigned char) d;
            *ImgPtr++ = (unsigned char) d;
        }
    }
    else
    {
        float range = (float) (wlevel - blevel);
        for (int i = 0; i < NPixels; i++, RawPtr++ )
        {
            float d;
            if (*RawPtr <= blevel)
                d = 0.0;
            else if (*RawPtr >= wlevel)
                d = 255.0;
            else
            {
                d = ((float) (*RawPtr) - (float) blevel) / range;
                d = pow(d, (float) power) * 255.0;
            }
            *ImgPtr++ = (unsigned char) d;
            *ImgPtr++ = (unsigned char) d;
            *ImgPtr++ = (unsigned char) d;
        }
    }

    *rawimg = img;
    return false;
}

bool usImage::BinnedCopyToImage(wxImage **rawimg, int blevel, int wlevel, double power) {
    wxImage *img;
    unsigned char *ImgPtr;
    unsigned short *RawPtr;
    int x,y;
    float d;
    //, s_factor;
    int full_xsize, full_ysize;
    int use_xsize, use_ysize;

{'fraction_non_alphanumeric': 0.12083622484385843, 'fraction_numerical': 0.011537126995142262, 'mean_word_length': 2.0908847184986596, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7094740', 'n_tokens_mistral': 3787, 'n_tokens_neox': 3577, 'n_words': 1252}