diff --git a/bin/muffin/main.cc b/bin/muffin/main.cc index ed12376..8cc6694 100644 --- a/bin/muffin/main.cc +++ b/bin/muffin/main.cc @@ -27,6 +27,7 @@ */ #include +#include extern "C" { #include #include @@ -41,6 +42,14 @@ //if (fork() == 0x0) { window->vCreate(); window->vSDECommand(1); +ogImage * image = new ogImage(); +ogSurface * bgImage = new ogSurface(); +//image->Load("/ubixos/var/background/ringed800_600.bmp", *bgImage); +image->Load("/ubixos/var/background/sphere800x600.bmp", *bgImage); +window->ogCopy(*bgImage); + window->vSDECommand(3); +while(1) + asm("nop"); while (1) { for (i=0x2;i<0xFF;i += 16) { for (ii=0x0;ii<0xFF;ii+= 16) { diff --git a/lib/objgfx/Makefile b/lib/objgfx/Makefile new file mode 100644 index 0000000..6c3f125 --- /dev/null +++ b/lib/objgfx/Makefile @@ -0,0 +1,43 @@ +# $Id: Makefile 89 2016-01-12 00:20:40Z reddawg $ +# Kernel Makefile (C) 2002 The UbixOS Project + +# Include Global 'Source' Options +#include ../../Makefile.incl +#include ../Makefile.incl + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = objgfx.o ogEdgeTable.o ogImage.o ogPixCon.o ogPixelFmt.o vWindow.o ogFont.o vWidget.o +#ogBlit.o + +#Include +INCLUDE = -I./objgfx +# -I../../lib/libc/include -I../../lib/libcpp/include + +#Output +OUTPUT = objgfx40.so + +$(OUTPUT): $(OBJS) + $(CC) -nostdlib -shared -Wl,-soname,$(OUTPUT) -o $(OUTPUT) $(OBJS) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -g -fno-inline -fno-exceptions -std=c++11 $(INCLUDE) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -fomit-frame-pointer -std=c++11 -c -o $@ $< + +.c.o: + $(CC) -Wall -O -I../../lib/libc/include -c -o $@ $< + +.c.s: + $(CC) -Wall -fomit-frame-pointer -O -I../../lib/libc/include -S -o $@ $< + +.S.o: + $(CC) -Wall -fomit-frame-pointer -c -o $@ $< + +# Clean up the junk +clean: + $(REMOVE) $(OBJS) $(BINARY) $(OUTPUT) *.core diff --git a/lib/objgfx/objgfx/ogFont.h b/lib/objgfx/objgfx/ogFont.h new file mode 100644 index 0000000..d1c0970 --- /dev/null +++ b/lib/objgfx/objgfx/ogFont.h @@ -0,0 +1,45 @@ +#ifndef OGFONT_H +#define OGFONT_H + +#include "objgfx.h" + +enum + ogTextAlign { + leftText, + bottomText = leftText, + centerText, + rightText, + topText = rightText + }; // textAlign + +class + ogBitFont { + protected: + uInt32 fontDataIdx[256]; + uInt32 charWidthTable[256]; + uInt32 charHeightTable[256]; + uInt8 * fontData; + uInt32 fontDataSize; + ogRGBA8 BGColour; + ogRGBA8 FGColour; + uInt16 numOfChars; + uInt8 width, height; + uInt8 startingChar; + public: + ogBitFont(); + void CenterTextX(ogSurface&, int32, const char *); + uInt32 GetWidth(void) const { return width; } + uInt32 GetHeight(void) const { return height; } + void JustifyText(ogSurface&, ogTextAlign, ogTextAlign, const char *); + bool Load(const char *, uInt32); + void PutChar(ogSurface&, int32, int32, const char); + void PutString(ogSurface&, int32, int32, const char *); +// bool Save(const char *); + void SetBGColor(uInt32, uInt32, uInt32, uInt32); + void SetFGColor(uInt32, uInt32, uInt32, uInt32); + uInt32 TextHeight(const char *); + uInt32 TextWidth(const char *); + ~ogBitFont(); +}; // ogBitFont + +#endif diff --git a/lib/objgfx/objgfx/vWidget.h b/lib/objgfx/objgfx/vWidget.h new file mode 100644 index 0000000..a5dfa96 --- /dev/null +++ b/lib/objgfx/objgfx/vWidget.h @@ -0,0 +1,17 @@ +#ifndef VWIDGET_H +#define VWIDGET_H + +#include "objgfx.h" + +class vWidget : public ogSurface { + protected: + bool active; + public: + vWidget(void) { active = true; } + virtual void vDraw(void) = 0; + virtual bool vGetActive(void) const { return active; } + virtual bool vSetActive(bool); + virtual bool vCreate(void) = 0; +}; + +#endif diff --git a/lib/objgfx/objgfx/vWindow.h b/lib/objgfx/objgfx/vWindow.h new file mode 100644 index 0000000..18252f1 --- /dev/null +++ b/lib/objgfx/objgfx/vWindow.h @@ -0,0 +1,19 @@ +#ifndef VWINDOW_H +#define VWINDOW_H + +#include "objgfx.h" +#include "ogFont.h" +#include "vWidget.h" + +class vWindow : public vWidget { + protected: + ogSurface * realWindow; + ogBitFont * titleFont; + public: + vWindow(void); + virtual void vDraw(void) { return; } + virtual bool vCreate(void); + void vSDECommand(uInt32); + virtual ~vWindow(void); +}; +#endif diff --git a/lib/objgfx/objgfx40.so b/lib/objgfx/objgfx40.so new file mode 100755 index 0000000..73d6ecd --- /dev/null +++ b/lib/objgfx/objgfx40.so Binary files differ diff --git a/lib/objgfx/ogFont.cpp b/lib/objgfx/ogFont.cpp new file mode 100644 index 0000000..0deeb43 --- /dev/null +++ b/lib/objgfx/ogFont.cpp @@ -0,0 +1,280 @@ +#include "ogFont.h" +#include "objgfx.h" + +extern "C" { +#ifdef __UBIXOS_KERNEL__ +#include +#include +#include +#else +#include +#include +#endif + +#include +} + +//using namespace std; + +typedef struct { + char ID[3]; + uint8_t version; + uint8_t width, height; + uint8_t numOfChars; + uint8_t startingChar; + uint8_t colourType; + uint8_t paddington[7]; +} ogDPFHeader; + +ogBitFont::ogBitFont(void) { + memset(fontDataIdx, 0, sizeof(fontDataIdx)); + memset(charWidthTable, 0, sizeof(charWidthTable)); + memset(charHeightTable, 0, sizeof(charHeightTable)); + + fontData = NULL; + fontDataSize = 0; + numOfChars = 0; + width = height = startingChar = 0; + + BGColour.red = 0; + BGColour.green = 0; + BGColour.blue = 0; + BGColour.alpha = 0; + + FGColour.red = 255; + FGColour.green = 255; + FGColour.blue = 255; + FGColour.alpha = 255; + + return; +} // ogBitFont::ogBitFont + +void ogBitFont::SetBGColor(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha) { + BGColour.red = red; + BGColour.green = green; + BGColour.blue = blue; + BGColour.alpha = alpha; + return; +} // ogBitFont::SetBGColor + +void ogBitFont::SetFGColor(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha) { + FGColour.red = red; + FGColour.green = green; + FGColour.blue = blue; + FGColour.alpha = alpha; + return; +} // ogBitFont::SetFGColor + +ogBitFont::~ogBitFont(void) { + memset(fontDataIdx, 0, sizeof(fontDataIdx)); + memset(charWidthTable, 0, sizeof(charWidthTable)); + memset(charHeightTable, 0, sizeof(charHeightTable)); + delete[] fontData; + fontData = NULL; + fontDataSize = 0; + width = height = startingChar = 0; + return; +} // ogBitFont::~ogBitFont; + +void ogBitFont::CenterTextX(ogSurface& dest, int32 y, const char * textString) { + int32 x; + x = ((dest.ogGetMaxX() + 1) - TextWidth(textString)) / 2; + PutString(dest, x, y, textString); + return; +} // ogBitFont::CenterTextX + +void ogBitFont::JustifyText(ogSurface& dest, ogTextAlign horiz, ogTextAlign vert, const char * textString) { + uint32_t x, y; + + switch (horiz) { + case leftText: + x = 0; + break; + case centerText: + x = ((dest.ogGetMaxX()) - TextWidth(textString)) / 2; + break; + case rightText: + x = (dest.ogGetMaxX()) - TextWidth(textString); + break; + default: + return; + } // switch + + switch (vert) { + case topText: + y = 0; + break; + case centerText: + y = ((dest.ogGetMaxY()) - TextHeight(textString)) / 2; + break; + case bottomText: + y = (dest.ogGetMaxY()) - TextHeight(textString); + default: + return; + } // switch + + PutString(dest, x, y, textString); + return; +} // ogBitFont::JustifyText + +bool ogBitFont::Load(const char* fontFile, uint32_t offset = 0) { +#ifdef __UBIXOS_KERNEL__ + fileDescriptor_t *infile; +#else + FILE * infile; +#endif + ogDPFHeader header; + uint32_t lresult, size; + + delete[] fontData; + + infile = fopen(fontFile, "r"); + + //fseek(infile, offset, SEEK_SET); + + lresult = fread(&header, sizeof(header), 1, infile); + width = header.width; + height = header.height; + numOfChars = header.numOfChars; + + if (numOfChars == 0) + numOfChars = 256; + + startingChar = header.startingChar; + + + memset(fontDataIdx, 0, sizeof(fontDataIdx)); + memset(charWidthTable, 0, sizeof(charWidthTable)); + memset(charHeightTable, 0, sizeof(charHeightTable)); + + size = (((uint32_t) width + 7) / 8) * (uint32_t) height; + fontDataSize = size * (uint32_t) numOfChars; + + for (int32 tmp = startingChar; tmp <= startingChar + (numOfChars - 1); tmp++) { + charWidthTable[tmp] = width; + charHeightTable[tmp] = height; + fontDataIdx[tmp] = (size * (tmp - startingChar)); + } // for tmp + + fontData = new uint8_t[fontDataSize]; + + fseek(infile, 16, 0); + lresult = fread(fontData, fontDataSize, 1, infile); + + fclose(infile); + return true; +} // ogBitFont::Load + +/* + bool + ogFont::LoadFrom(const char* FontFile, uint32_t Offset) { + return true; + } // ogFont::LoadFrom + + + bool + ogFont::Save(const char* FontFile) { + return saveTo(FontFile,0); + } // ogFont::Save + */ + +uint32_t ogBitFont::TextHeight(const char * textString) { + uint32_t size, tmpsize; + size = 0; + const unsigned char * text = (const unsigned char *) textString; + + if (text != NULL) + while (*text) { + tmpsize = charHeightTable[*text++]; + if (tmpsize > size) + size = tmpsize; + } // while + + return size; +} // ogBitFont::TextHeight + +uint32_t ogBitFont::TextWidth(const char * textString) { + uint32_t size = 0; + const unsigned char * text = (const unsigned char *) textString; + + if (text != NULL) + while (*text) + size += charWidthTable[*text++]; + return size; +} // ogBitFont::TextWidth + +/* + bool + ogBitFont::SaveTo(const char * fontFile, int32 offset) { + return true; + } // TDPFont::SaveTo + */ + +void ogBitFont::PutChar(ogSurface& dest, int32 x, int32 y, const char ch) { + + uint32_t xx, xCount, yCount; + uint32_t BGC, FGC, tColour; + uint8_t * offset; + uint8_t bits = 0; + + const unsigned char c = (const unsigned char) ch; + + if (fontData == NULL) + return; + + if (!dest.ogAvail()) + return; + + if (charWidthTable[c] != 0) { + BGC = dest.ogPack(BGColour.red, BGColour.green, BGColour.blue, BGColour.alpha); + + BGC &= dest.ogGetAlphaMasker(); + + tColour = dest.ogGetTransparentColor(); + + FGC = dest.ogPack(FGColour.red, FGColour.green, FGColour.blue, FGColour.alpha); + + offset = fontData; + offset += fontDataIdx[c]; + + for (yCount = 0; yCount < height; yCount++) { + xCount = charWidthTable[c]; + xx = 0; + + do { + if ((xx & 7) == 0) + bits = *(offset++); + if ((bits & 128) != 0) + dest.ogSetPixel(x + xx, y + yCount, FGColour.red, FGColour.green, FGColour.blue, FGColour.alpha); + else if (BGC != tColour) + dest.ogSetPixel(x + xx, y + yCount, BGC); + + bits += bits; + ++xx; + } while (--xCount); + } // for yCount + } // if + return; +} // ogBitFont::PutChar + +void ogBitFont::PutString(ogSurface& dest, int32 x, int32 y, const char *textString) { + + const unsigned char *text; + unsigned char ch; + + if (textString == NULL) + return; + if (0 == strlen(textString)) + return; + if (!dest.ogAvail()) + return; + + text = (const unsigned char *) textString; + + while ((ch = *text++) != 0) { + PutChar(dest, x, y, ch); + x += charWidthTable[ch]; + } // while + + return; +} // ogBitFont::PutString diff --git a/lib/objgfx/ogImage.cpp b/lib/objgfx/ogImage.cpp index 8d60c54..d1596ac 100644 --- a/lib/objgfx/ogImage.cpp +++ b/lib/objgfx/ogImage.cpp @@ -1,576 +1,576 @@ -#include -#include -#include -#include -#include -#include - -#include "ogImage.h" -#include "objgfx.h" - -bool Win3xBitmapHeader::Deserialize(std::istream& stream) -{ - if (!stream) return false; - - // Read in each field, and check for any failure. Return false on failure - if (!stream.read(reinterpret_cast(&ImageFileType), sizeof(ImageFileType))) return false; - if (!stream.read(reinterpret_cast(&FileSize), sizeof(FileSize))) return false; - if (!stream.read(reinterpret_cast(&Reserved1), sizeof(Reserved1))) return false; - if (!stream.read(reinterpret_cast(&Reserved2), sizeof(Reserved2))) return false; - if (!stream.read(reinterpret_cast(&ImageDataOffset), sizeof(ImageDataOffset))) return false; - - return true; -} // bool Win3xBitmapHeader::Deserialize() - -std::string Win3xBitmapHeader::ToString() -{ - return - "ImageFileType = " + std::to_string(ImageFileType) + "\r\n" + - "FileSize = " + std::to_string(FileSize) + "\r\n" + - "Reserved1 = " + std::to_string(Reserved1) + "\r\n" + - "Reserved2 = " + std::to_string(Reserved2) + "\r\n" + - "ImageDataOffset = " + std::to_string(ImageDataOffset) + "\r\n"; -} // string Win3xBitmapHeader::ToString() - -bool Win3xBitmapHeader::IsMatch() -{ - return - (ImageFileType == 0x4D42 && - FileSize != 0 && - Reserved1 == 0 && - Reserved2 == 0 && - ImageDataOffset != 0); -} // bool Win3xBitmapHeader::IsMatch() - -bool Win3xBitmapHeader::Serialize(std::ostream& stream) -{ - if (!stream) return false; - - // Read in each field, and check for any failure. Return false on failure - if (!stream.write(reinterpret_cast(&ImageFileType), sizeof(ImageFileType))) return false; - if (!stream.write(reinterpret_cast(&FileSize), sizeof(FileSize))) return false; - if (!stream.write(reinterpret_cast(&Reserved1), sizeof(Reserved1))) return false; - if (!stream.write(reinterpret_cast(&Reserved2), sizeof(Reserved2))) return false; - if (!stream.write(reinterpret_cast(&ImageDataOffset), sizeof(ImageDataOffset))) return false; - - return true; -} // bool Win3xBitmapHeader::Serialize() - -size_t Win3xBitmapHeader::Size() -{ - return - sizeof(ImageFileType) + - sizeof(FileSize) + - sizeof(Reserved1) + - sizeof(Reserved2) + - sizeof(ImageDataOffset); -} // size_t Win3xBitmapHeader::Size() - -bool Win3xBitmapInfoHeader::Deserialize(std::istream& stream) -{ - if (!stream) return false; - - // Read in each field, and check for any failure. Return false on failure - if (!stream.read(reinterpret_cast(&HeaderSize), sizeof(HeaderSize))) return false; - if (!stream.read(reinterpret_cast(&ImageWidth), sizeof(ImageWidth))) return false; - if (!stream.read(reinterpret_cast(&ImageHeight), sizeof(ImageHeight))) return false; - if (!stream.read(reinterpret_cast(&NumberOfImagePlanes), sizeof(NumberOfImagePlanes))) return false; - if (!stream.read(reinterpret_cast(&BitsPerPixel), sizeof(BitsPerPixel))) return false; - if (!stream.read(reinterpret_cast(&CompressionMethod), sizeof(CompressionMethod))) return false; - if (!stream.read(reinterpret_cast(&SizeOfBitmap), sizeof(SizeOfBitmap))) return false; - if (!stream.read(reinterpret_cast(&HorzResolution), sizeof(HorzResolution))) return false; - if (!stream.read(reinterpret_cast(&VertResolution), sizeof(VertResolution))) return false; - if (!stream.read(reinterpret_cast(&NumColoursUsed), sizeof(NumColoursUsed))) return false; - if (!stream.read(reinterpret_cast(&NumSignificantColours), sizeof(NumSignificantColours))) return false; - - return true; -} // bool Win3xBitmapInfoHeader::Deserialize() - -std::string Win3xBitmapInfoHeader::ToString() -{ - return - "HeaderSize = " + std::to_string(HeaderSize) + "\r\n" + - "ImageWidth = " + std::to_string(ImageWidth) + "\r\n" + - "ImageHeight = " + std::to_string(ImageHeight) + "\r\n" + - "NumberOfImagePlanes = " + std::to_string(NumberOfImagePlanes) + "\r\n" + - "BitsPerPixel = "+ std::to_string(BitsPerPixel) + "\r\n" + - "CompressionMethod = " + std::to_string(CompressionMethod) + "\r\n" + - "SizeOfBitmap = " + std::to_string(SizeOfBitmap) + "\r\n" + - "HorzResolution = " + std::to_string(HorzResolution) + "\r\n" + - "VertResolution = " + std::to_string(VertResolution) + "\r\n" + - "NumColoursUsed = " + std::to_string(NumColoursUsed) + "\r\n" + - "NumSignificantColours = " + std::to_string(NumSignificantColours) + "\r\n"; -} // string Win3xBitmapInfoHeader::ToString() - -bool Win3xBitmapInfoHeader::IsMatch() -{ - return - (HeaderSize != 0 && - ImageWidth != 0 && - ImageHeight != 0 && - CompressionMethod == 0 && - (BitsPerPixel == 8 || BitsPerPixel == 24)); -} -bool Win3xBitmapInfoHeader::Serialize(std::ostream& stream) -{ - if (!stream) return false; - - // Read in each field, and return false on failure - if (!stream.write(reinterpret_cast(&HeaderSize), sizeof(HeaderSize))) return false; - if (!stream.write(reinterpret_cast(&ImageWidth), sizeof(ImageWidth))) return false; - if (!stream.write(reinterpret_cast(&ImageHeight), sizeof(ImageHeight))) return false; - if (!stream.write(reinterpret_cast(&NumberOfImagePlanes), sizeof(NumberOfImagePlanes))) return false; - if (!stream.write(reinterpret_cast(&BitsPerPixel), sizeof(BitsPerPixel))) return false; - if (!stream.write(reinterpret_cast(&CompressionMethod), sizeof(CompressionMethod))) return false; - if (!stream.write(reinterpret_cast(&SizeOfBitmap), sizeof(SizeOfBitmap))) return false; - if (!stream.write(reinterpret_cast(&HorzResolution), sizeof(HorzResolution))) return false; - if (!stream.write(reinterpret_cast(&VertResolution), sizeof(VertResolution))) return false; - if (!stream.write(reinterpret_cast(&NumColoursUsed), sizeof(NumColoursUsed))) return false; - if (!stream.write(reinterpret_cast(&NumSignificantColours), sizeof(NumSignificantColours))) return false; - - return true; -} // bool Win3xBitmapInfoHeader::Serialize() - -size_t Win3xBitmapInfoHeader::Size() -{ - return - sizeof(HeaderSize) + - sizeof(ImageWidth) + - sizeof(ImageHeight) + - sizeof(NumberOfImagePlanes) + - sizeof(BitsPerPixel) + - sizeof(CompressionMethod) + - sizeof(SizeOfBitmap) + - sizeof(HorzResolution) + - sizeof(VertResolution) + - sizeof(NumColoursUsed) + - sizeof(NumSignificantColours); -} // size_t Win3xBitmapInfoHeader::Size() - -bool RGBQuad::Deserialize(std::istream& stream) -{ - if (!stream) return false; - - // Read in each field, and return false on failure - if (!stream.read(reinterpret_cast(&rgbBlue), sizeof(rgbBlue))) return false; - if (!stream.read(reinterpret_cast(&rgbGreen), sizeof(rgbGreen))) return false; - if (!stream.read(reinterpret_cast(&rgbRed), sizeof(rgbRed))) return false; - if (!stream.read(reinterpret_cast(&rgbReserved), sizeof(rgbReserved))) return false; - - return true; -} // bool RGBQuad::Deserialize() - -std::string RGBQuad::ToString() -{ - return "rgbRed = " + to_string(rgbRed) + "\r\n" - + "rgbGreen = " + to_string(rgbGreen) + "\r\n" - + "rgbBlue = " + to_string(rgbBlue) + "\r\n" - + "rgbReserved = " + to_string(rgbReserved) + "\r\n"; -} // string RGBQuad::ToString() - -bool RGBQuad::Serialize(std::ostream& stream) -{ - if (!stream) return false; - - // Read in each field, and return false on failure - if (!stream.write(reinterpret_cast(&rgbBlue), sizeof(rgbBlue))) return false; - if (!stream.write(reinterpret_cast(&rgbGreen), sizeof(rgbGreen))) return false; - if (!stream.write(reinterpret_cast(&rgbRed), sizeof(rgbRed))) return false; - if (!stream.write(reinterpret_cast(&rgbReserved), sizeof(rgbReserved))) return false; - - return true; -} // bool RGBQuad::Serialize() -size_t RGBQuad::Size() -{ - return - sizeof(rgbBlue) + - sizeof(rgbGreen) + - sizeof(rgbRed) + - sizeof(rgbReserved); -} // size_t RGBQuad::Size() - -bool IsBMP(std::istream& stream) -{ - - // Check for BMP - Win3xBitmapHeader bmpHeader; - bmpHeader.Deserialize(stream); - Win3xBitmapInfoHeader bmpInfoHeader; - bmpInfoHeader.Deserialize(stream); - - if (bmpHeader.IsMatch() && bmpInfoHeader.IsMatch()) - { - std::cout << bmpHeader.ToString(); - std::cout << bmpInfoHeader.ToString(); - return true; - } - return false; -} // bool IsBMP() - -/********************************************** - * ogImage - **********************************************/ -static const std::map>& CreateIsImageMap() -{ - static std::map> IsImage; - - //IsImage[NoImage] = ([&](std::istream&) -> bool { return false; }); - IsImage[BMP] = &IsBMP; - return IsImage; -} // map<> CreateIsImageMap() - -std::map> ogImage::IsImage = CreateIsImageMap(); - -ogImage::ogImage() : - surface(nullptr), - options(nullptr), - input(nullptr), - output(nullptr) -{ - Decode[NoImage] = &ogImage::NoOp; - Decode[BMP] = &ogImage::DecodeBMP; - - Encode[NoImage] = &ogImage::NoOp; - Encode[BMP] = &ogImage::EncodeBMP; - -} // ogImage::ogImage() - -bool ogImage::DecodeBMP() -{ - // ogImage::ImageType() has determined we're a BMP, so we only need to do - // minimal sanity checks on the header information. - - Win3xBitmapHeader bmpHeader; - Win3xBitmapInfoHeader bmpInfoHeader; - if (!bmpHeader.Deserialize(*input)) return false; - if (!bmpInfoHeader.Deserialize(*input)) return false; - - size_t lineSize; - size_t paddington; - char linePadding[4]; - - if (bmpInfoHeader.BitsPerPixel == 8) - { - if (!surface->ogCreate(bmpInfoHeader.ImageWidth, bmpInfoHeader.ImageHeight, OG_PIXFMT_8BPP)) return false; - - lineSize = ((bmpInfoHeader.ImageWidth+3) >> 2) << 2; // round up to the nearest 4 bytes - paddington = lineSize - bmpInfoHeader.ImageWidth; // see if we have a remainder - - if (paddington > 4) return false; // this would be odd - - RGBQuad quad; - for (unsigned colour = 0; colour < 256; colour++) - { - if (!quad.Deserialize(*input)) return false; - surface->ogSetPalette(colour, quad.rgbRed, quad.rgbGreen, quad.rgbBlue, quad.rgbReserved); - } // for colour - - for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) // y goes to 0 - { - char * ptr = reinterpret_cast(surface->ogGetPtr(0, y)); - if (ptr == nullptr) return false; // this doesn't have to be a complete failure, fix later - if (!input->read(ptr, bmpInfoHeader.ImageWidth)) return false; - if (paddington != 0) - { - if (!input->read(linePadding, paddington)) return false; // double check this - } - } // for y - } - else if (bmpInfoHeader.BitsPerPixel == 24) - { - ogPixelFmt BMPPixelFmt(24, 16,8,0,0, 8,8,8,0); - if (!surface->ogCreate(bmpInfoHeader.ImageWidth, bmpInfoHeader.ImageHeight, OG_PIXFMT_24BPP)) return false; - size_t widthInBytes = bmpInfoHeader.ImageWidth*3; // 3 represents how many bytes per pixel - lineSize = ((widthInBytes+3) >> 2) << 2; // round up to the nearest 4 bytes - paddington = lineSize - widthInBytes; // see if we have a remainder - - if (paddington > 4) return false; - - for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) - { - char * ptr = reinterpret_cast(surface->ogGetPtr(0, y)); - if (ptr == nullptr) return false; // this doesn't have to be a complete failure, fix later - if (!input->read(ptr, widthInBytes)) return false; - if (paddington != 0) - { - if (!input->read(linePadding, paddington)) return false; - } - } // for y - } - - return true; -} // bool ogImage::DecodeBMP() - -bool ogImage::EncodeBMP() -{ - Win3xBitmapHeader bmpHeader; - Win3xBitmapInfoHeader bmpInfoHeader; - size_t paddington; - size_t lineSize; - const char linePadding[4] = {0,0,0,0}; - ogRGBA8 ogPalette[256]; // used to get the palette from the surface - - bmpHeader.ImageFileType = 0x4D42; - bmpHeader.FileSize = 0; // fill in later - //bmpHeader.Reserved1 = 0; // set by constructor - //bmpHeader.Reserved2 = 0; // set by constructor - bmpHeader.ImageDataOffset = bmpHeader.Size() + bmpInfoHeader.Size(); - - bmpInfoHeader.HeaderSize = bmpInfoHeader.Size(); - bmpInfoHeader.ImageWidth = surface->ogGetMaxX()+1; - bmpInfoHeader.ImageHeight = surface->ogGetMaxY()+1; - bmpInfoHeader.NumberOfImagePlanes = 1; - // bmpInfoHeader.BitsPerPixel is set below - bmpInfoHeader.CompressionMethod = 0; - bmpInfoHeader.SizeOfBitmap = 0; - bmpInfoHeader.HorzResolution = 0; // option - bmpInfoHeader.VertResolution = 0; // option - - switch (surface->ogGetBPP()) - { - case 8: - bmpInfoHeader.BitsPerPixel = 8; // 8bpp, 256 colours - bmpInfoHeader.NumColoursUsed = 1 << surface->ogGetBPP(); - bmpInfoHeader.NumSignificantColours = 0; // option - - // This is hard to calculate dynamically. Sod it. - bmpHeader.ImageDataOffset += 1024;// adjust by palette size - - lineSize = ((bmpInfoHeader.ImageWidth+3) >> 2) << 2; // multiple of 4 - bmpInfoHeader.SizeOfBitmap = lineSize*bmpInfoHeader.ImageHeight; - bmpHeader.FileSize = bmpHeader.ImageDataOffset+bmpInfoHeader.SizeOfBitmap; - - // Write the headers - if (!bmpHeader.Serialize(*output)) return false; - if (!bmpInfoHeader.Serialize(*output)) return false; - - // all rows are aligned to the nearest 4 bytes. Figure out if we need to pad. - paddington = lineSize-bmpInfoHeader.ImageWidth; - - surface->ogGetPalette(ogPalette); - - for (size_t index = 0; index < sizeof(ogPalette) / sizeof(ogPalette[0]); index++) - { - RGBQuad quad(ogPalette[index]); - if (!quad.Serialize(*output)) return false; - } // for index - - for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) // y goes to 0 - { - char * ptr = reinterpret_cast(surface->ogGetPtr(0, y)); - if (ptr != nullptr) - { - if (!output->write(ptr, bmpInfoHeader.ImageWidth)) return false; - } - - // Is there any padding to add to the end of the line? - if (paddington != 0) - { - if (!output->write(linePadding, paddington)) return false; - } - } // for y - break; - case 32: - case 24: - case 16: - case 15: - // 15, 16, and 32 bpp are all treated as 24bpp - bmpInfoHeader.BitsPerPixel = 24; - bmpInfoHeader.NumColoursUsed = 0; - bmpInfoHeader.NumSignificantColours = 0; - - lineSize = ((bmpInfoHeader.ImageWidth*3+3) >> 2) << 2; - bmpInfoHeader.SizeOfBitmap = lineSize*bmpInfoHeader.ImageHeight; - bmpHeader.FileSize = bmpHeader.ImageDataOffset+bmpInfoHeader.SizeOfBitmap; - - // Write the headers - if (!bmpHeader.Serialize(*output)) return false; - if (!bmpInfoHeader.Serialize(*output)) return false; - - // all rows are aligned to the nearest 4 bytes. Figure out if we need to pad. - paddington = lineSize-bmpInfoHeader.ImageWidth*3; // 3 represents how many bytes per pixel - uInt8 red, green, blue; - - for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) // y goes to 0 - { - for (unsigned x = 0; x <= surface->ogGetMaxX(); x++) - { - // Unpack the pixel and write it out. - surface->ogUnpack(surface->ogGetPixel(x, y), red, green, blue); - if (!output->write(reinterpret_cast(&blue), sizeof(blue))) return false; - if (!output->write(reinterpret_cast(&green), sizeof(green))) return false; - if (!output->write(reinterpret_cast(&red), sizeof(red))) return false; - } // for x - - // Is there any padding to add to the end of the line? - if (paddington != 0) - { - if (!output->write(linePadding, paddington)) return false; - } - } // for y - break; - default: - return false; // we can't encode anything else (I'm not sure there *is* anything else) - } // switch - - - return true; -} // bool ogImage::EncodeBMP() - -ogImageType ogImage::ImageType(std::istream& input) -{ - ogImageType imageType = NoImage; - // space for the header - char header[128]; // This really should be as large as the largest header we know of - - for (size_t index = 0; index < std::extent::value; index++) - { - header[index] = 0; // clear the header - } // for index - - size_t size = sizeof(header); - - if (!input.read(header, size)) return NoImage; // This isn't necessarily true. Might just be a small image. - // Figure out how many bytes we read in. - streamsize bytesRead = input.gcount(); - - if (bytesRead != 0) - { - - // Try to determine what it really is - for (auto iType : IsImage) - { - mstream mb(header, bytesRead); - // This creates a new istream from a memory stream, - // which is wrapped adound the header. - //istream stream(&mstream(header, bytesRead)); - istream stream(&mb); - if (iType.second(stream)) // Did we find it? - { - imageType = iType.first; // Found it - break; - } // if - } // for iType - - // Now seek backwards in the stream. - input.seekg(-bytesRead, std::ios_base::cur); - } - - return imageType; -} // ogImageType ogImage::ImageType() - -ogImageType ogImage::ImageType(const std::string& filename) -{ - std::ifstream input(filename, ios::in | std::ios_base::binary); - ogImageType imageType = NoImage; - - // Sanity check - if (input) - { - // Use the stream version - imageType = ogImage::ImageType(input); - - // close the file - input.close(); - } // if - - return imageType; -} // ogImageType ogImage::ImageType() - -bool ogImage::Load(const std::string& filename, ogSurface & surface) -{ - std::cout << "Loading " << filename << std::endl; - bool success = false; // assume failure - - ifstream stream(filename, ios_base::in | ios_base::binary); - - if (stream) - { - success = Load(stream, surface); - stream.close(); - } // if stream - - return success; -} // ogSurface * ogImage::Load() - -bool ogImage::Load(std::istream& stream, ogSurface& surface) -{ - // First we need to find out what type of graphics file it is: - ogImageType imageType = ogImage::ImageType(stream); - - if (imageType == NoImage) return false; - - this->surface = &surface; - this->input = &stream; - this->options = nullptr; // shouldn't be necessary - this->output = nullptr; // shouldn't be necessary - - assert(Decode.count(imageType) == 1); // make sure we can handle it - - return (this->*Decode[imageType])(); // Decode -} // bool ogImage::Load() - -bool ogImage::Save(const std::string& filename, - ogSurface &surface, - ogImageType imageType, - ogImageOptions * options) -{ - bool success = false; // assume failure - - ofstream stream(filename, ios_base::out | ios_base::binary); // try to open the file - - if (stream) - { - // Use the stream version - success = Save(stream, surface, imageType, options); - - // close the file - stream.close(); - } // if - - return success; -} // bool ogImage::Save() - -bool ogImage::Save(std::ostream& stream, - ogSurface &surface, - ogImageType imageType, - ogImageOptions * options) -{ - bool success = false; // assume failure - - if (stream && surface.ogAvail()) - { - // Since surface is a reference, it cannot [normally] be null, - // so no checking needs to be done in any of the encoder functions. - this->surface = &surface; - this->options = options; - this->output = &stream; - - assert(Encode.count(imageType) == 1); // Sanity check - - // Call the specific encoder - success = (this->*Encode[imageType])(); - } // if - - return success; -} // bool ogImage::Save() - -#if 0 -class membuf : public basic_streambuf -{ -public: - membuf(char* p, size_t n) { - setg(p, p, p + n); - setp(p, p + n); - } -} -Usage: - -char *mybuffer; -size_t length; -// ... allocate "mybuffer", put data into it, set "length" - -membuf mb(mybuffer, length); -istream reader(&mb); -// use "reader" -#endif \ No newline at end of file +#include +#include +#include +#include +#include +#include + +#include "ogImage.h" +#include "objgfx.h" + +bool Win3xBitmapHeader::Deserialize(std::istream& stream) +{ + if (!stream) return false; + + // Read in each field, and check for any failure. Return false on failure + if (!stream.read(reinterpret_cast(&ImageFileType), sizeof(ImageFileType))) return false; + if (!stream.read(reinterpret_cast(&FileSize), sizeof(FileSize))) return false; + if (!stream.read(reinterpret_cast(&Reserved1), sizeof(Reserved1))) return false; + if (!stream.read(reinterpret_cast(&Reserved2), sizeof(Reserved2))) return false; + if (!stream.read(reinterpret_cast(&ImageDataOffset), sizeof(ImageDataOffset))) return false; + + return true; +} // bool Win3xBitmapHeader::Deserialize() + +std::string Win3xBitmapHeader::ToString() +{ + return + "ImageFileType = " + std::to_string(ImageFileType) + "\r\n" + + "FileSize = " + std::to_string(FileSize) + "\r\n" + + "Reserved1 = " + std::to_string(Reserved1) + "\r\n" + + "Reserved2 = " + std::to_string(Reserved2) + "\r\n" + + "ImageDataOffset = " + std::to_string(ImageDataOffset) + "\r\n"; +} // string Win3xBitmapHeader::ToString() + +bool Win3xBitmapHeader::IsMatch() +{ + return + (ImageFileType == 0x4D42 && + FileSize != 0 && + Reserved1 == 0 && + Reserved2 == 0 && + ImageDataOffset != 0); +} // bool Win3xBitmapHeader::IsMatch() + +bool Win3xBitmapHeader::Serialize(std::ostream& stream) +{ + if (!stream) return false; + + // Read in each field, and check for any failure. Return false on failure + if (!stream.write(reinterpret_cast(&ImageFileType), sizeof(ImageFileType))) return false; + if (!stream.write(reinterpret_cast(&FileSize), sizeof(FileSize))) return false; + if (!stream.write(reinterpret_cast(&Reserved1), sizeof(Reserved1))) return false; + if (!stream.write(reinterpret_cast(&Reserved2), sizeof(Reserved2))) return false; + if (!stream.write(reinterpret_cast(&ImageDataOffset), sizeof(ImageDataOffset))) return false; + + return true; +} // bool Win3xBitmapHeader::Serialize() + +size_t Win3xBitmapHeader::Size() +{ + return + sizeof(ImageFileType) + + sizeof(FileSize) + + sizeof(Reserved1) + + sizeof(Reserved2) + + sizeof(ImageDataOffset); +} // size_t Win3xBitmapHeader::Size() + +bool Win3xBitmapInfoHeader::Deserialize(std::istream& stream) +{ + if (!stream) return false; + + // Read in each field, and check for any failure. Return false on failure + if (!stream.read(reinterpret_cast(&HeaderSize), sizeof(HeaderSize))) return false; + if (!stream.read(reinterpret_cast(&ImageWidth), sizeof(ImageWidth))) return false; + if (!stream.read(reinterpret_cast(&ImageHeight), sizeof(ImageHeight))) return false; + if (!stream.read(reinterpret_cast(&NumberOfImagePlanes), sizeof(NumberOfImagePlanes))) return false; + if (!stream.read(reinterpret_cast(&BitsPerPixel), sizeof(BitsPerPixel))) return false; + if (!stream.read(reinterpret_cast(&CompressionMethod), sizeof(CompressionMethod))) return false; + if (!stream.read(reinterpret_cast(&SizeOfBitmap), sizeof(SizeOfBitmap))) return false; + if (!stream.read(reinterpret_cast(&HorzResolution), sizeof(HorzResolution))) return false; + if (!stream.read(reinterpret_cast(&VertResolution), sizeof(VertResolution))) return false; + if (!stream.read(reinterpret_cast(&NumColoursUsed), sizeof(NumColoursUsed))) return false; + if (!stream.read(reinterpret_cast(&NumSignificantColours), sizeof(NumSignificantColours))) return false; + + return true; +} // bool Win3xBitmapInfoHeader::Deserialize() + +std::string Win3xBitmapInfoHeader::ToString() +{ + return + "HeaderSize = " + std::to_string(HeaderSize) + "\r\n" + + "ImageWidth = " + std::to_string(ImageWidth) + "\r\n" + + "ImageHeight = " + std::to_string(ImageHeight) + "\r\n" + + "NumberOfImagePlanes = " + std::to_string(NumberOfImagePlanes) + "\r\n" + + "BitsPerPixel = "+ std::to_string(BitsPerPixel) + "\r\n" + + "CompressionMethod = " + std::to_string(CompressionMethod) + "\r\n" + + "SizeOfBitmap = " + std::to_string(SizeOfBitmap) + "\r\n" + + "HorzResolution = " + std::to_string(HorzResolution) + "\r\n" + + "VertResolution = " + std::to_string(VertResolution) + "\r\n" + + "NumColoursUsed = " + std::to_string(NumColoursUsed) + "\r\n" + + "NumSignificantColours = " + std::to_string(NumSignificantColours) + "\r\n"; +} // string Win3xBitmapInfoHeader::ToString() + +bool Win3xBitmapInfoHeader::IsMatch() +{ + return + (HeaderSize != 0 && + ImageWidth != 0 && + ImageHeight != 0 && + CompressionMethod == 0 && + (BitsPerPixel == 8 || BitsPerPixel == 24)); +} +bool Win3xBitmapInfoHeader::Serialize(std::ostream& stream) +{ + if (!stream) return false; + + // Read in each field, and return false on failure + if (!stream.write(reinterpret_cast(&HeaderSize), sizeof(HeaderSize))) return false; + if (!stream.write(reinterpret_cast(&ImageWidth), sizeof(ImageWidth))) return false; + if (!stream.write(reinterpret_cast(&ImageHeight), sizeof(ImageHeight))) return false; + if (!stream.write(reinterpret_cast(&NumberOfImagePlanes), sizeof(NumberOfImagePlanes))) return false; + if (!stream.write(reinterpret_cast(&BitsPerPixel), sizeof(BitsPerPixel))) return false; + if (!stream.write(reinterpret_cast(&CompressionMethod), sizeof(CompressionMethod))) return false; + if (!stream.write(reinterpret_cast(&SizeOfBitmap), sizeof(SizeOfBitmap))) return false; + if (!stream.write(reinterpret_cast(&HorzResolution), sizeof(HorzResolution))) return false; + if (!stream.write(reinterpret_cast(&VertResolution), sizeof(VertResolution))) return false; + if (!stream.write(reinterpret_cast(&NumColoursUsed), sizeof(NumColoursUsed))) return false; + if (!stream.write(reinterpret_cast(&NumSignificantColours), sizeof(NumSignificantColours))) return false; + + return true; +} // bool Win3xBitmapInfoHeader::Serialize() + +size_t Win3xBitmapInfoHeader::Size() +{ + return + sizeof(HeaderSize) + + sizeof(ImageWidth) + + sizeof(ImageHeight) + + sizeof(NumberOfImagePlanes) + + sizeof(BitsPerPixel) + + sizeof(CompressionMethod) + + sizeof(SizeOfBitmap) + + sizeof(HorzResolution) + + sizeof(VertResolution) + + sizeof(NumColoursUsed) + + sizeof(NumSignificantColours); +} // size_t Win3xBitmapInfoHeader::Size() + +bool RGBQuad::Deserialize(std::istream& stream) +{ + if (!stream) return false; + + // Read in each field, and return false on failure + if (!stream.read(reinterpret_cast(&rgbBlue), sizeof(rgbBlue))) return false; + if (!stream.read(reinterpret_cast(&rgbGreen), sizeof(rgbGreen))) return false; + if (!stream.read(reinterpret_cast(&rgbRed), sizeof(rgbRed))) return false; + if (!stream.read(reinterpret_cast(&rgbReserved), sizeof(rgbReserved))) return false; + + return true; +} // bool RGBQuad::Deserialize() + +std::string RGBQuad::ToString() +{ + return "rgbRed = " + to_string(rgbRed) + "\r\n" + + "rgbGreen = " + to_string(rgbGreen) + "\r\n" + + "rgbBlue = " + to_string(rgbBlue) + "\r\n" + + "rgbReserved = " + to_string(rgbReserved) + "\r\n"; +} // string RGBQuad::ToString() + +bool RGBQuad::Serialize(std::ostream& stream) +{ + if (!stream) return false; + + // Read in each field, and return false on failure + if (!stream.write(reinterpret_cast(&rgbBlue), sizeof(rgbBlue))) return false; + if (!stream.write(reinterpret_cast(&rgbGreen), sizeof(rgbGreen))) return false; + if (!stream.write(reinterpret_cast(&rgbRed), sizeof(rgbRed))) return false; + if (!stream.write(reinterpret_cast(&rgbReserved), sizeof(rgbReserved))) return false; + + return true; +} // bool RGBQuad::Serialize() +size_t RGBQuad::Size() +{ + return + sizeof(rgbBlue) + + sizeof(rgbGreen) + + sizeof(rgbRed) + + sizeof(rgbReserved); +} // size_t RGBQuad::Size() + +bool IsBMP(std::istream& stream) +{ + + // Check for BMP + Win3xBitmapHeader bmpHeader; + bmpHeader.Deserialize(stream); + Win3xBitmapInfoHeader bmpInfoHeader; + bmpInfoHeader.Deserialize(stream); + + if (bmpHeader.IsMatch() && bmpInfoHeader.IsMatch()) + { + std::cout << bmpHeader.ToString(); + std::cout << bmpInfoHeader.ToString(); + return true; + } + return false; +} // bool IsBMP() + +/********************************************** + * ogImage + **********************************************/ +static const std::map>& CreateIsImageMap() +{ + static std::map> IsImage; + + //IsImage[NoImage] = ([&](std::istream&) -> bool { return false; }); + IsImage[BMP] = &IsBMP; + return IsImage; +} // map<> CreateIsImageMap() + +std::map> ogImage::IsImage = CreateIsImageMap(); + +ogImage::ogImage() : + surface(nullptr), + options(nullptr), + input(nullptr), + output(nullptr) +{ + Decode[NoImage] = &ogImage::NoOp; + Decode[BMP] = &ogImage::DecodeBMP; + + Encode[NoImage] = &ogImage::NoOp; + Encode[BMP] = &ogImage::EncodeBMP; + +} // ogImage::ogImage() + +bool ogImage::DecodeBMP() +{ + // ogImage::ImageType() has determined we're a BMP, so we only need to do + // minimal sanity checks on the header information. + + Win3xBitmapHeader bmpHeader; + Win3xBitmapInfoHeader bmpInfoHeader; + if (!bmpHeader.Deserialize(*input)) return false; + if (!bmpInfoHeader.Deserialize(*input)) return false; + + size_t lineSize; + size_t paddington; + char linePadding[4]; + + if (bmpInfoHeader.BitsPerPixel == 8) + { + if (!surface->ogCreate(bmpInfoHeader.ImageWidth, bmpInfoHeader.ImageHeight, OG_PIXFMT_8BPP)) return false; + + lineSize = ((bmpInfoHeader.ImageWidth+3) >> 2) << 2; // round up to the nearest 4 bytes + paddington = lineSize - bmpInfoHeader.ImageWidth; // see if we have a remainder + + if (paddington > 4) return false; // this would be odd + + RGBQuad quad; + for (unsigned colour = 0; colour < 256; colour++) + { + if (!quad.Deserialize(*input)) return false; + surface->ogSetPalette(colour, quad.rgbRed, quad.rgbGreen, quad.rgbBlue, quad.rgbReserved); + } // for colour + + for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) // y goes to 0 + { + char * ptr = reinterpret_cast(surface->ogGetPtr(0, y)); + if (ptr == nullptr) return false; // this doesn't have to be a complete failure, fix later + if (!input->read(ptr, bmpInfoHeader.ImageWidth)) return false; + if (paddington != 0) + { + if (!input->read(linePadding, paddington)) return false; // double check this + } + } // for y + } + else if (bmpInfoHeader.BitsPerPixel == 24) + { + ogPixelFmt BMPPixelFmt(24, 16,8,0,0, 8,8,8,0); + if (!surface->ogCreate(bmpInfoHeader.ImageWidth, bmpInfoHeader.ImageHeight, OG_PIXFMT_24BPP)) return false; + size_t widthInBytes = bmpInfoHeader.ImageWidth*3; // 3 represents how many bytes per pixel + lineSize = ((widthInBytes+3) >> 2) << 2; // round up to the nearest 4 bytes + paddington = lineSize - widthInBytes; // see if we have a remainder + + if (paddington > 4) return false; + + for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) + { + char * ptr = reinterpret_cast(surface->ogGetPtr(0, y)); + if (ptr == nullptr) return false; // this doesn't have to be a complete failure, fix later + if (!input->read(ptr, widthInBytes)) return false; + if (paddington != 0) + { + if (!input->read(linePadding, paddington)) return false; + } + } // for y + } + + return true; +} // bool ogImage::DecodeBMP() + +bool ogImage::EncodeBMP() +{ + Win3xBitmapHeader bmpHeader; + Win3xBitmapInfoHeader bmpInfoHeader; + size_t paddington; + size_t lineSize; + const char linePadding[4] = {0,0,0,0}; + ogRGBA8 ogPalette[256]; // used to get the palette from the surface + + bmpHeader.ImageFileType = 0x4D42; + bmpHeader.FileSize = 0; // fill in later + //bmpHeader.Reserved1 = 0; // set by constructor + //bmpHeader.Reserved2 = 0; // set by constructor + bmpHeader.ImageDataOffset = bmpHeader.Size() + bmpInfoHeader.Size(); + + bmpInfoHeader.HeaderSize = bmpInfoHeader.Size(); + bmpInfoHeader.ImageWidth = surface->ogGetMaxX()+1; + bmpInfoHeader.ImageHeight = surface->ogGetMaxY()+1; + bmpInfoHeader.NumberOfImagePlanes = 1; + // bmpInfoHeader.BitsPerPixel is set below + bmpInfoHeader.CompressionMethod = 0; + bmpInfoHeader.SizeOfBitmap = 0; + bmpInfoHeader.HorzResolution = 0; // option + bmpInfoHeader.VertResolution = 0; // option + + switch (surface->ogGetBPP()) + { + case 8: + bmpInfoHeader.BitsPerPixel = 8; // 8bpp, 256 colours + bmpInfoHeader.NumColoursUsed = 1 << surface->ogGetBPP(); + bmpInfoHeader.NumSignificantColours = 0; // option + + // This is hard to calculate dynamically. Sod it. + bmpHeader.ImageDataOffset += 1024;// adjust by palette size + + lineSize = ((bmpInfoHeader.ImageWidth+3) >> 2) << 2; // multiple of 4 + bmpInfoHeader.SizeOfBitmap = lineSize*bmpInfoHeader.ImageHeight; + bmpHeader.FileSize = bmpHeader.ImageDataOffset+bmpInfoHeader.SizeOfBitmap; + + // Write the headers + if (!bmpHeader.Serialize(*output)) return false; + if (!bmpInfoHeader.Serialize(*output)) return false; + + // all rows are aligned to the nearest 4 bytes. Figure out if we need to pad. + paddington = lineSize-bmpInfoHeader.ImageWidth; + + surface->ogGetPalette(ogPalette); + + for (size_t index = 0; index < sizeof(ogPalette) / sizeof(ogPalette[0]); index++) + { + RGBQuad quad(ogPalette[index]); + if (!quad.Serialize(*output)) return false; + } // for index + + for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) // y goes to 0 + { + char * ptr = reinterpret_cast(surface->ogGetPtr(0, y)); + if (ptr != nullptr) + { + if (!output->write(ptr, bmpInfoHeader.ImageWidth)) return false; + } + + // Is there any padding to add to the end of the line? + if (paddington != 0) + { + if (!output->write(linePadding, paddington)) return false; + } + } // for y + break; + case 32: + case 24: + case 16: + case 15: + // 15, 16, and 32 bpp are all treated as 24bpp + bmpInfoHeader.BitsPerPixel = 24; + bmpInfoHeader.NumColoursUsed = 0; + bmpInfoHeader.NumSignificantColours = 0; + + lineSize = ((bmpInfoHeader.ImageWidth*3+3) >> 2) << 2; + bmpInfoHeader.SizeOfBitmap = lineSize*bmpInfoHeader.ImageHeight; + bmpHeader.FileSize = bmpHeader.ImageDataOffset+bmpInfoHeader.SizeOfBitmap; + + // Write the headers + if (!bmpHeader.Serialize(*output)) return false; + if (!bmpInfoHeader.Serialize(*output)) return false; + + // all rows are aligned to the nearest 4 bytes. Figure out if we need to pad. + paddington = lineSize-bmpInfoHeader.ImageWidth*3; // 3 represents how many bytes per pixel + uInt8 red, green, blue; + + for (unsigned y = surface->ogGetMaxY()+1; y --> 0 ;) // y goes to 0 + { + for (unsigned x = 0; x <= surface->ogGetMaxX(); x++) + { + // Unpack the pixel and write it out. + surface->ogUnpack(surface->ogGetPixel(x, y), red, green, blue); + if (!output->write(reinterpret_cast(&blue), sizeof(blue))) return false; + if (!output->write(reinterpret_cast(&green), sizeof(green))) return false; + if (!output->write(reinterpret_cast(&red), sizeof(red))) return false; + } // for x + + // Is there any padding to add to the end of the line? + if (paddington != 0) + { + if (!output->write(linePadding, paddington)) return false; + } + } // for y + break; + default: + return false; // we can't encode anything else (I'm not sure there *is* anything else) + } // switch + + + return true; +} // bool ogImage::EncodeBMP() + +ogImageType ogImage::ImageType(std::istream& input) +{ + ogImageType imageType = NoImage; + // space for the header + char header[128]; // This really should be as large as the largest header we know of + + for (size_t index = 0; index < std::extent::value; index++) + { + header[index] = 0; // clear the header + } // for index + + size_t size = sizeof(header); + + if (!input.read(header, size)) return NoImage; // This isn't necessarily true. Might just be a small image. + // Figure out how many bytes we read in. + streamsize bytesRead = input.gcount(); + + if (bytesRead != 0) + { + + // Try to determine what it really is + for (auto iType : IsImage) + { + mstream mb(header, bytesRead); + // This creates a new istream from a memory stream, + // which is wrapped adound the header. + //istream stream(&mstream(header, bytesRead)); + istream stream(&mb); + if (iType.second(stream)) // Did we find it? + { + imageType = iType.first; // Found it + break; + } // if + } // for iType + + // Now seek backwards in the stream. + input.seekg(-bytesRead, std::ios_base::cur); + } + + return imageType; +} // ogImageType ogImage::ImageType() + +ogImageType ogImage::ImageType(const std::string& filename) +{ + std::ifstream input(filename, ios::in | std::ios_base::binary); + ogImageType imageType = NoImage; + + // Sanity check + if (input) + { + // Use the stream version + imageType = ogImage::ImageType(input); + + // close the file + input.close(); + } // if + + return imageType; +} // ogImageType ogImage::ImageType() + +bool ogImage::Load(const std::string& filename, ogSurface & surface) +{ + std::cout << "Loading " << filename << std::endl; + bool success = false; // assume failure + + ifstream stream(filename, ios_base::in | ios_base::binary); + + if (stream) + { + success = Load(stream, surface); + stream.close(); + } // if stream + + return success; +} // ogSurface * ogImage::Load() + +bool ogImage::Load(std::istream& stream, ogSurface& surface) +{ + // First we need to find out what type of graphics file it is: + ogImageType imageType = ogImage::ImageType(stream); + + if (imageType == NoImage) return false; + + this->surface = &surface; + this->input = &stream; + this->options = nullptr; // shouldn't be necessary + this->output = nullptr; // shouldn't be necessary + + assert(Decode.count(imageType) == 1); // make sure we can handle it + + return (this->*Decode[imageType])(); // Decode +} // bool ogImage::Load() + +bool ogImage::Save(const std::string& filename, + ogSurface &surface, + ogImageType imageType, + ogImageOptions * options) +{ + bool success = false; // assume failure + + ofstream stream(filename, ios_base::out | ios_base::binary); // try to open the file + + if (stream) + { + // Use the stream version + success = Save(stream, surface, imageType, options); + + // close the file + stream.close(); + } // if + + return success; +} // bool ogImage::Save() + +bool ogImage::Save(std::ostream& stream, + ogSurface &surface, + ogImageType imageType, + ogImageOptions * options) +{ + bool success = false; // assume failure + + if (stream && surface.ogAvail()) + { + // Since surface is a reference, it cannot [normally] be null, + // so no checking needs to be done in any of the encoder functions. + this->surface = &surface; + this->options = options; + this->output = &stream; + + assert(Encode.count(imageType) == 1); // Sanity check + + // Call the specific encoder + success = (this->*Encode[imageType])(); + } // if + + return success; +} // bool ogImage::Save() + +#if 0 +class membuf : public basic_streambuf +{ +public: + membuf(char* p, size_t n) { + setg(p, p, p + n); + setp(p, p + n); + } +} +Usage: + +char *mybuffer; +size_t length; +// ... allocate "mybuffer", put data into it, set "length" + +membuf mb(mybuffer, length); +istream reader(&mb); +// use "reader" +#endif diff --git a/lib/objgfx/vWidget.cpp b/lib/objgfx/vWidget.cpp new file mode 100644 index 0000000..38a4924 --- /dev/null +++ b/lib/objgfx/vWidget.cpp @@ -0,0 +1,9 @@ +#include "vWidget.h" + +bool +vWidget::vSetActive(bool _active) { + bool result = active; + active = _active; + return result; +} // vWidget::vSetActive + diff --git a/lib/objgfx/vWindow.cpp b/lib/objgfx/vWindow.cpp new file mode 100644 index 0000000..afef9b1 --- /dev/null +++ b/lib/objgfx/vWindow.cpp @@ -0,0 +1,63 @@ +extern "C" { + #include +} + +#include "vWindow.h" + +vWindow::vWindow(void) { + realWindow = new ogSurface(); + titleFont = new ogBitFont(); + return; +} // vWindow::vWindow + +bool +vWindow::vCreate(void) { + if (realWindow->ogCreate(800,600,OG_PIXFMT_24BPP) == false) return false; + if (ogAlias(*realWindow, // window + 0, 0, // [x1, y1] + realWindow->ogGetMaxX(), realWindow->ogGetMaxY()) // [x2, y2] + == false) return false; + return true; +} // vWindow::vCreate + +//void vWindow::vSDECommand(uint32_t command); + +extern "C" { +void vSDECmd(uint32_t command, void *realWindow); +asm( + ".globl vSDECmd\n" + "vSDECmd:\n" + "movl $40,%eax\n" + "int $0x81\n" + "ret\n" + ); +} + + +void vWindow::vSDECommand(uint32_t command) { +printf("REAL WINDOW: 0x%X\n", realWindow); + asm( + "pushl %%ebx\n" + "pushl %%ecx\n" + "int %0\n" + "add $0x8, %%esp\n" + : + : "i" (0x81),"a" (40),"b" (command),"c" (realWindow) + ); +//vSDECmd(command, realWindow); + return; +} // vWindow::vSDECommand + +vWindow::~vWindow() { + delete realWindow; + delete titleFont; + return; +} // vWindow::~vWindow + +/* +ogSurface -> vWidget -> vWindow + | \------> vButton + | + | + -- ogDisplay_UbixOS -> SDE +*/ diff --git a/sys/vmm/paging.c b/sys/vmm/paging.c index fc6d48f..79f328a 100644 --- a/sys/vmm/paging.c +++ b/sys/vmm/paging.c @@ -395,7 +395,7 @@ for (i = 0; i < PD_ENTRIES; i++) { if ((childPageDir[i] & PAGE_PRESENT) == PAGE_PRESENT) { - kprintf("mapping: 0x%X\n", i); + //kprintf("mapping: 0x%X\n", i); if (vmm_remapPage(childPageDir[i], 0x5A01000 + (i * 0x1000), KERNEL_PAGE_DEFAULT, _current->id, 0) == 0x0) K_PANIC("Returned NULL"); } @@ -403,7 +403,7 @@ kprintf("mapping completed\n"); //for (x = (_current->oInfo.vmStart / (1024 * 4096)); x < 1024; x++) { for (x = PD_INDEX(VMM_KERN_START); x < PD_INDEX(VMM_KERN_END); x++) { - kpanic("v_mFT"); + //kpanic("v_mFT"); pageTableSrc = (uint32_t *) (PT_BASE_ADDR + (4096 * x)); for (y = 0; y < 1024; y++) { @@ -435,8 +435,8 @@ } - kprintf("dI: 0x%X", dI); if ((childPageDir[dI] & PAGE_PRESENT) == PAGE_PRESENT) { + kprintf("dI: 0x%X\n", dI); childPageTable = (uint32_t *) (0x5A01000 + (0x1000 * dI)); if ((childPageTable[tI + c] & PAGE_PRESENT) == PAGE_PRESENT) { @@ -461,8 +461,8 @@ //Map A Physical Page To The Virtual Page childPageTable = (uint32_t *) (0x5A01000 + (0x1000 * dI)); - kprintf("eDI: 0x%X", dI); if ((childPageDir[dI] & PAGE_PRESENT) == PAGE_PRESENT) { + kprintf("eDI: 0x%X", dI); if ((childPageTable[tI] & PAGE_PRESENT) == PAGE_PRESENT) { if (vmm_remapPage(childPageTable[tI], ((x * (1024 * 4096)) + (y * 4096)), KERNEL_PAGE_DEFAULT, _current->id, 0) == 0x0) K_PANIC("remap Failed");