mirror of
https://github.com/dbalsom/x86_microcode.git
synced 2026-06-23 13:17:20 +03:00
Initial 80386 microcode commit.
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
#include "alfe/main.h"
|
||||
|
||||
#ifndef INCLUDED_BITMAP_H
|
||||
#define INCLUDED_BITMAP_H
|
||||
|
||||
#include "alfe/colour_space.h"
|
||||
#include "alfe/vectors.h"
|
||||
|
||||
template<class Pixel> class Bitmap;
|
||||
|
||||
template<class Pixel> class BitmapFileFormat : public Handle
|
||||
{
|
||||
public:
|
||||
Bitmap<Pixel> load(const File& file) const
|
||||
{
|
||||
return body()->load(file);
|
||||
}
|
||||
void save(Bitmap<Pixel>& bitmap, const File& file) const
|
||||
{
|
||||
return body()->save(bitmap, file);
|
||||
}
|
||||
protected:
|
||||
class Body : public Handle::Body
|
||||
{
|
||||
public:
|
||||
virtual void save(Bitmap<Pixel>& bitmap, const File& file) const = 0;
|
||||
virtual Bitmap<Pixel> load(const File& file) const = 0;
|
||||
};
|
||||
BitmapFileFormat(const Handle& handle) : Handle(handle) { }
|
||||
Body* body() { return as<Body>(); }
|
||||
const Body* body() const { return as<Body>(); }
|
||||
private:
|
||||
friend class Bitmap<Pixel>;
|
||||
};
|
||||
|
||||
template<class T> class RawFileFormatTemplate;
|
||||
typedef RawFileFormatTemplate<SRGB> RawFileFormat;
|
||||
|
||||
template<class T> class RawFileFormatTemplate : public BitmapFileFormat<T>
|
||||
{
|
||||
public:
|
||||
RawFileFormatTemplate(Vector size)
|
||||
: BitmapFileFormat(this->create<Body>(size)) { }
|
||||
private:
|
||||
class Body : public BitmapFileFormat<T>::Body
|
||||
{
|
||||
public:
|
||||
Body(Vector size) : _size(size) { }
|
||||
// The bitmap needs to be 8-bit sRGB data for this to work.
|
||||
virtual void save(Bitmap<T>& bitmap, const File& file) const
|
||||
{
|
||||
FileStream stream = file.openWrite();
|
||||
Byte* data = bitmap.data();
|
||||
int stride = bitmap.stride();
|
||||
Vector size = bitmap.size();
|
||||
for (int y = 0; y < size.y; ++y) {
|
||||
stream.write(static_cast<void*>(data), size.x*sizeof(T));
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
// This will put 8-bit sRGB data in the bitmap.
|
||||
virtual Bitmap<T> load(const File& file) const
|
||||
{
|
||||
FileStream stream = file.openRead();
|
||||
Bitmap<SRGB> bitmap(_size);
|
||||
Byte* data = bitmap.data();
|
||||
int stride = bitmap.stride();
|
||||
for (int y = 0; y < _size.y; ++y) {
|
||||
stream.read(static_cast<void*>(data), _size.x*sizeof(T));
|
||||
data += stride;
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
private:
|
||||
Vector _size;
|
||||
};
|
||||
};
|
||||
|
||||
// A Bitmap is a value class encapsulating a 2D image. Its width, height,
|
||||
// stride and pixel format are immutable but the pixels themselves are not.
|
||||
template<class Pixel> class Bitmap : private Array<Pixel>
|
||||
{
|
||||
public:
|
||||
Bitmap() : _size(0, 0) { }
|
||||
Bitmap(Vector size)
|
||||
{
|
||||
_stride = size.x*sizeof(Pixel);
|
||||
_size = size;
|
||||
this->allocate(size.x*size.y);
|
||||
_topLeft = reinterpret_cast<Byte*>(&Array<Pixel>::operator[](0));
|
||||
}
|
||||
void ensure(Vector s)
|
||||
{
|
||||
if (size().x < s.x || size().y < s.y)
|
||||
*this = Bitmap(Vector(max(size().x, s.x), max(size().y, s.y)));
|
||||
}
|
||||
|
||||
// Convert from one pixel format to another.
|
||||
template<class TargetPixel, class Converter> void convert(
|
||||
Bitmap<TargetPixel>& target, Converter converter)
|
||||
{
|
||||
Byte* row = data();
|
||||
Byte* targetRow = target.data();
|
||||
for (int y = 0; y < _size.y; ++y) {
|
||||
Pixel* p = reinterpret_cast<Pixel*>(row);
|
||||
TargetPixel* tp = reinterpret_cast<TargetPixel*>(targetRow);
|
||||
for (int x = 0; x < _size.x; ++x) {
|
||||
*tp = converter.convert(*p);
|
||||
++p;
|
||||
++tp;
|
||||
}
|
||||
row += _stride;
|
||||
targetRow += target.stride();
|
||||
}
|
||||
}
|
||||
|
||||
void load(const BitmapFileFormat<Pixel>& format, const File& file)
|
||||
{
|
||||
*this = format.load(file);
|
||||
}
|
||||
|
||||
void save(const BitmapFileFormat<Pixel>& format, const File& file)
|
||||
{
|
||||
format.save(*this, file);
|
||||
}
|
||||
Byte* data() { return _topLeft; }
|
||||
const Byte* data() const { return _topLeft; }
|
||||
int stride() const { return _stride; }
|
||||
Vector size() const { return _size; }
|
||||
bool valid() const { return _size.x != 0; }
|
||||
Pixel* row(int y)
|
||||
{
|
||||
return reinterpret_cast<Pixel*>(_topLeft + y*_stride);
|
||||
}
|
||||
Pixel& operator[](Vector position) { return row(position.y)[position.x]; }
|
||||
|
||||
// A sub-bitmap of a bitmap is a pointer into the same set of data, so
|
||||
// drawing on a subBitmap will also draw on the parent bitmap, and any
|
||||
// other overlapping sub-bitmaps. This can be used in conjunction with
|
||||
// fill() to draw rectangles. To avoid this behavior, use
|
||||
// subBitmap().clone().
|
||||
Bitmap subBitmap(Vector topLeft, Vector size)
|
||||
{
|
||||
return Bitmap(*this,
|
||||
_topLeft + topLeft.x*sizeof(Pixel) + topLeft.y*_stride, size,
|
||||
_stride);
|
||||
}
|
||||
|
||||
Bitmap clone() const
|
||||
{
|
||||
Bitmap c(_size);
|
||||
copyTo(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
void fill(const Pixel& pixel)
|
||||
{
|
||||
Byte* row = data();
|
||||
for (int y = 0; y < _size.y; ++y) {
|
||||
Pixel* p = reinterpret_cast<Pixel*>(row);
|
||||
for (int x = 0; x < _size.x; ++x) {
|
||||
*p = pixel;
|
||||
++p;
|
||||
}
|
||||
row += _stride;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy with pixel format conversion but no resizing. Bitmaps must be the
|
||||
// same dimensions.
|
||||
template<class OtherPixel> void copyFrom(const Bitmap<OtherPixel>& other)
|
||||
{
|
||||
Byte* row = data();
|
||||
const Byte* otherRow = other.data();
|
||||
for (int y = 0; y < _size.y; ++y) {
|
||||
Pixel* p = reinterpret_cast<Pixel*>(row);
|
||||
const OtherPixel* op =
|
||||
reinterpret_cast<const OtherPixel*>(otherRow);
|
||||
for (int x = 0; x < _size.x; ++x) {
|
||||
*p = *op;
|
||||
++p;
|
||||
++op;
|
||||
}
|
||||
row += _stride;
|
||||
otherRow += other._stride;
|
||||
}
|
||||
}
|
||||
template<class OtherPixel> void copyTo(Bitmap<OtherPixel>& other) const
|
||||
{
|
||||
other.copyFrom(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
Bitmap(Array<Pixel> array, Byte* topLeft, Vector size, int stride)
|
||||
: Array(array), _topLeft(topLeft), _size(size), _stride(stride) { }
|
||||
|
||||
Vector _size;
|
||||
Byte* _topLeft;
|
||||
int _stride;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_BITMAP_H
|
||||
Reference in New Issue
Block a user