<commit_before>#include "lib/bitmap.h"

#include "lib/rgba_colour.h"
#include "lib/common.h"

#include <math.h>
#include <memory.h>
#include <stdlib.h>


BitmapRGBA *CreateBitmapRGBA(unsigned width, unsigned height)
{
	BitmapRGBA *bmp = new BitmapRGBA;
	bmp->width = width;
	bmp->height = height;
	bmp->pixels = new RGBAColour[width * height];
	bmp->lines = new RGBAColour *[height];

	DebugAssert(bmp->pixels && bmp->lines);

	for (unsigned y = 0; y < height; ++y)
		bmp->lines[y] = &bmp->pixels[y * width];

    return bmp;
}


void DeleteBitmapRGBA(BitmapRGBA *bmp)
{
	bmp->width = -1;
	bmp->height = -1;
	delete [] bmp->pixels;
	delete [] bmp->lines;
	bmp->pixels = NULL;
	bmp->lines = NULL;
}


#define GetLine(bmp, y) ((bmp)->pixels + (bmp)->width * (y))


void ClearBitmap(BitmapRGBA *bmp, RGBAColour colour)
{
    RectFill(bmp, 0, 0, bmp->width, bmp->height, colour);
}


RGBAColour GetPixUnclipped(BitmapRGBA *bmp, unsigned x, unsigned y)
{
	return GetLine(bmp, y)[x];
}


void PutPix(BitmapRGBA *bmp, unsigned x, unsigned y, RGBAColour colour)
{
	if (x >= bmp->width || y >= bmp->height)
		return;

	PutPixUnclipped(bmp, x, y, colour);
}


RGBAColour GetPix(BitmapRGBA *bmp, unsigned x, unsigned y)
{
	if (x >= bmp->width || y >= bmp->height)
		return g_colourBlack;

	return GetLine(bmp, y)[x]; 
}


void HLineUnclipped(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    RGBAColour *row = GetLine(bmp, y) + x;
    if (c.a == 255)
    {
        for (unsigned i = 0; i < len; i++)
            row[i] = c;
    }
    else
    {
        unsigned char invA = 255 - c.a;
        for (unsigned i = 0; i < len; i++)
        {
            RGBAColour *pixel = row + i;
            pixel->r = (pixel->r * invA + c.r * c.a) / 255;
            pixel->g = (pixel->g * invA + c.g * c.a) / 255;
            pixel->b = (pixel->b * invA + c.b * c.a) / 255;
        }
    }
}


void HLine(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    // Clip against top and bottom of bmp
    if (unsigned(y) >= bmp->height)
        return;

    // Clip against left
    if (x < 0)
    {
        len += x;
        x = 0;
    }

    // Clip against right
    if (x + (int)len > int(bmp->width))
    {
        if (x > (int)bmp->width)
            return;

        len = bmp->width - x;
    }

    HLineUnclipped(bmp, x, y, len, c);
}


void VLineUnclipped(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    RGBAColour *pixel = GetLine(bmp, y) + x;
    unsigned const bw = bmp->width;
    if (c.a == 255)
    {
        for (unsigned i = 0; i < len; i++)
        {
            *pixel = c;
            pixel += bw;
        }
    }
    else
    {
        unsigned char invA = 255 - c.a;
        for (unsigned i = 0; i < len; i++)
        {
            pixel->r = (pixel->r * invA + c.r * c.a) / 255;
            pixel->g = (pixel->g * invA + c.g * c.a) / 255;
            pixel->b = (pixel->b * invA + c.b * c.a) / 255;
            pixel += bw;
        }
    }
}


void VLine(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    // Clip against left and right of bmp
    if (unsigned(x) > bmp->width)
        return;

    // Clip against top
    if (y < 0)
    {
        len += y;
        y = 0;
    }

    // Clip against bottom
    if (y + (int)len > int(bmp->height))
    {<commit_msg>Fixed more clipping bugs (when len=0 and x or y is negative)<commit_after>#include "lib/bitmap.h"

#include "lib/rgba_colour.h"
#include "lib/common.h"

#include <math.h>
#include <memory.h>
#include <stdlib.h>


BitmapRGBA *CreateBitmapRGBA(unsigned width, unsigned height)
{
	BitmapRGBA *bmp = new BitmapRGBA;
	bmp->width = width;
	bmp->height = height;
	bmp->pixels = new RGBAColour[width * height];
	bmp->lines = new RGBAColour *[height];

	DebugAssert(bmp->pixels && bmp->lines);

	for (unsigned y = 0; y < height; ++y)
		bmp->lines[y] = &bmp->pixels[y * width];

    return bmp;
}


void DeleteBitmapRGBA(BitmapRGBA *bmp)
{
	bmp->width = -1;
	bmp->height = -1;
	delete [] bmp->pixels;
	delete [] bmp->lines;
	bmp->pixels = NULL;
	bmp->lines = NULL;
}


#define GetLine(bmp, y) ((bmp)->pixels + (bmp)->width * (y))


void ClearBitmap(BitmapRGBA *bmp, RGBAColour colour)
{
    RectFill(bmp, 0, 0, bmp->width, bmp->height, colour);
}


RGBAColour GetPixUnclipped(BitmapRGBA *bmp, unsigned x, unsigned y)
{
	return GetLine(bmp, y)[x];
}


void PutPix(BitmapRGBA *bmp, unsigned x, unsigned y, RGBAColour colour)
{
	if (x >= bmp->width || y >= bmp->height)
		return;

	PutPixUnclipped(bmp, x, y, colour);
}


RGBAColour GetPix(BitmapRGBA *bmp, unsigned x, unsigned y)
{
	if (x >= bmp->width || y >= bmp->height)
		return g_colourBlack;

	return GetLine(bmp, y)[x]; 
}


void HLineUnclipped(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    RGBAColour *row = GetLine(bmp, y) + x;
    if (c.a == 255)
    {
        for (unsigned i = 0; i < len; i++)
            row[i] = c;
    }
    else
    {
        unsigned char invA = 255 - c.a;
        for (unsigned i = 0; i < len; i++)
        {
            RGBAColour *pixel = row + i;
            pixel->r = (pixel->r * invA + c.r * c.a) / 255;
            pixel->g = (pixel->g * invA + c.g * c.a) / 255;
            pixel->b = (pixel->b * invA + c.b * c.a) / 255;
        }
    }
}


void HLine(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    // Clip against top and bottom of bmp
    if (unsigned(y) >= bmp->height)
        return;

    if (len == 0)
        return;

    // Clip against left
    if (x < 0)
    {
        len += x;
        x = 0;
    }

    // Clip against right
    if (x + (int)len > int(bmp->width))
    {
        if (x > (int)bmp->width)
            return;

        len = bmp->width - x;
    }

    HLineUnclipped(bmp, x, y, len, c);
}


void VLineUnclipped(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    RGBAColour *pixel = GetLine(bmp, y) + x;
    unsigned const bw = bmp->width;
    if (c.a == 255)
    {
        for (unsigned i = 0; i < len; i++)
        {
            *pixel = c;
            pixel += bw;
        }
    }
    else
    {
        unsigned char invA = 255 - c.a;
        for (unsigned i = 0; i < len; i++)
        {
            pixel->r = (pixel->r * invA + c.r * c.a) / 255;
            pixel->g = (pixel->g * invA + c.g * c.a) / 255;
            pixel->b = (pixel->b * invA + c.b * c.a) / 255;
            pixel += bw;
        }
    }
}


void VLine(BitmapRGBA *bmp, int x, int y, unsigned len, RGBAColour c)
{
    if (len == 0)
        return;

    // Clip against left and right of bmp
    if (unsigned(x) > bmp->width)
        return;

    // Clip against top
    if (y < 0)
    {
        len += y;
        y = 0;
    }

    // Clip against bottom
    if (y + (int)len > int(bmp->height))
    {
{'fraction_non_alphanumeric': 0.16076455771225368, 'fraction_numerical': 0.013187138835383019, 'mean_word_length': 2.0405405405405403, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 109, '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': '2052323', 'n_tokens_mistral': 2823, 'n_tokens_neox': 2647, 'n_words': 709}