Files
danbooru/lib/danbooru_image_resizer/RowBuffer.h
2011-08-22 17:46:20 -04:00

138 lines
2.8 KiB
C++

#ifndef ROW_BUFFER_H
#define ROW_BUFFER_H
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "RowBuffer.h"
#include <algorithm>
using namespace std;
template<typename T>
class RowBuffer
{
public:
RowBuffer()
{
m_Rows = NULL;
m_ActualRows = NULL;
m_StartRow = 0;
m_EndRow = 0;
m_BPP = 0;
m_Height = 0;
}
~RowBuffer()
{
for(int i = 0; i < m_Height; ++i)
delete [] m_Rows[i];
delete [] m_ActualRows;
}
/*
* If iVertPadding is non-zero, simulate padding on the top and bottom of the image. After
* row 0 is written, rows [-1 ... -iVertPadding] will point to the same row. After the bottom
* row is written, the following iVertPadding will also point to the last row. These rows
* are discarded when the row they refer to is discarded.
*/
bool Init(int iWidth, int iHeight, int iBPP, int iVertPadding = 0)
{
m_Width = iWidth;
m_Height = iHeight;
m_BPP = iBPP;
m_iVertPadding = iVertPadding;
m_ActualRows = new T *[iHeight + iVertPadding*2];
m_Rows = m_ActualRows + iVertPadding;
memset(m_ActualRows, 0, sizeof(T *) * (iHeight + iVertPadding*2));
return true;
}
/* Return row, allocating if necessary. */
T *GetRow(int Row)
{
assert(m_BPP > 0);
if(m_Rows[Row] == NULL)
{
m_Rows[Row] = new T[m_Width*m_BPP];
if(Row == 0)
{
for(int i = -m_iVertPadding; i < 0; ++i)
m_Rows[i] = m_Rows[0];
}
if(Row == m_Height - 1)
{
for(int i = m_Height; i < m_Height + m_iVertPadding; ++i)
m_Rows[i] = m_Rows[m_Height - 1];
}
if(m_Rows[Row] == NULL)
return NULL;
if(m_StartRow == m_EndRow)
{
m_StartRow = Row;
m_EndRow = m_StartRow + 1;
}
}
if(int(Row) == m_StartRow+1)
{
while(m_StartRow != 0 && m_Rows[m_StartRow-1])
--m_StartRow;
}
if(int(Row) == m_EndRow)
{
while(m_EndRow < m_Height && m_Rows[m_EndRow])
++m_EndRow;
}
return m_Rows[Row];
}
// Free rows [0,DiscardRow).
void DiscardRows(int DiscardRow)
{
assert(m_BPP > 0);
if(DiscardRow > m_Height)
DiscardRow = m_Height;
for(int i = m_StartRow; i < DiscardRow; ++i)
{
delete [] m_Rows[i];
m_Rows[i] = NULL;
}
m_StartRow = max(m_StartRow, DiscardRow);
m_EndRow = max(m_EndRow, DiscardRow);
}
/* Get a range of rows allocated in m_Rows: [m_StartRow,m_EndRow). If
* more than one allocated range exists, which range is returned is undefined. */
int GetStartRow() const { return m_StartRow; }
int GetEndRow() const { return m_EndRow; }
const T *const *GetRows() const { return m_Rows; }
private:
/* Array of image rows. These are allocated as needed. */
T **m_Rows;
/* The actual pointer m_Rows is contained in. m_Rows may be offset from this to
* implement padding. */
T **m_ActualRows;
/* in m_Rows is allocated: */
int m_StartRow;
int m_EndRow;
int m_Width;
int m_Height;
int m_BPP;
int m_iVertPadding;
};
#endif