mirror of
https://github.com/fadden/ciderpress.git
synced 2024-12-22 20:29:51 +00:00
c78017b1d2
Moved comments and return types, switched to uint types, added "override" keyword.
310 lines
9.5 KiB
C++
310 lines
9.5 KiB
C++
/*
|
|
* CiderPress
|
|
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
|
* See the file LICENSE for distribution terms.
|
|
*/
|
|
/*
|
|
* Convert the various Super HiRes formats.
|
|
*/
|
|
#ifndef REFORMAT_SUPERHIRES_H
|
|
#define REFORMAT_SUPERHIRES_H
|
|
|
|
#include "ReformatBase.h"
|
|
|
|
/*
|
|
* Reformat SHR images (abstract base class).
|
|
*
|
|
* THOUGHT: add a "convert single line" function that copies to bytes or
|
|
* RGBTRIPLEs or whatever. Use it in the usual functions and for converting
|
|
* odd-sized APF-format images. Args are the bits for the line, 320/640 mode
|
|
* for source-pixel interpretation, and the color palette for that line. We
|
|
* need to orient less on the format we're converting *to* (e.g. 320/640x200)
|
|
* and more on what we're converting *from* (arbitrary sized image with
|
|
* certain GS-specific characteristics).
|
|
*/
|
|
class ReformatSHR : public ReformatGraphics {
|
|
public:
|
|
enum {
|
|
kNumLines = 200,
|
|
kPixelBytesPerLine = 160,
|
|
kNumColorTables = 16,
|
|
kNumEntriesPerColorTable = 16,
|
|
kColorTableEntrySize = 2,
|
|
kOutputWidth = 640, // use pixel-doubling so we can get both
|
|
kOutputHeight = 400, // 320 and 640 modes
|
|
kTotalSize = 32768,
|
|
kMaxPixelsPerScan = 1280, // allow up to 1280x1024
|
|
kMaxScanLines = 1024, // in APF images
|
|
|
|
kSCBColorTableMask = 0x0f,
|
|
kSCBFillMode = 0x20,
|
|
kSCBInterrupts = 0x40,
|
|
kSCBNumPixels = 0x80, // 0=320, 1=640
|
|
};
|
|
|
|
/*
|
|
* This holds one SHR screen; the size must be 32768 bytes.
|
|
*/
|
|
typedef struct SHRScreen {
|
|
uint8_t pixels[kNumLines * kPixelBytesPerLine];
|
|
uint8_t scb[kNumLines];
|
|
uint8_t reserved[256 - kNumLines];
|
|
uint8_t colorTable[kNumColorTables * kNumEntriesPerColorTable *
|
|
kColorTableEntrySize];
|
|
} SHRScreen;
|
|
|
|
/* convert 0RGB into (R,G,B) */
|
|
void GSColor(int color, RGBTRIPLE* pTriple) {
|
|
pTriple->rgbtRed = ((color >> 8) & 0x0f) * 17;
|
|
pTriple->rgbtGreen = ((color >> 4) & 0x0f) * 17;
|
|
pTriple->rgbtBlue = (color & 0x0f) * 17;
|
|
}
|
|
void GSColor(int color, RGBQUAD* pQuad) {
|
|
pQuad->rgbRed = ((color >> 8) & 0x0f) * 17;
|
|
pQuad->rgbGreen = ((color >> 4) & 0x0f) * 17;
|
|
pQuad->rgbBlue = (color & 0x0f) * 17;
|
|
pQuad->rgbReserved = 0;
|
|
}
|
|
|
|
/* 16 palettes of 16 colors */
|
|
RGBQUAD fColorTables[kNumColorTables][kNumEntriesPerColorTable];
|
|
|
|
MyDIBitmap* SHRScreenToBitmap8(const SHRScreen* pScreen);
|
|
MyDIBitmap* SHRDataToBitmap8(const uint8_t* pPixels,
|
|
const uint8_t* pSCB, const uint8_t* pColorTable,
|
|
int pixelBytesPerLine, int numScanLines,
|
|
int outputWidth, int outputHeight);
|
|
};
|
|
|
|
/*
|
|
* Reformat an unpacked SHR graphic into a bitmap.
|
|
*/
|
|
class ReformatUnpackedSHR : public ReformatSHR {
|
|
public:
|
|
ReformatUnpackedSHR(void) {}
|
|
virtual ~ReformatUnpackedSHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
SHRScreen fScreen;
|
|
};
|
|
|
|
/*
|
|
* Reformat an unpacked ".APP" SHR graphic from John Elway Quarterback GS
|
|
* into a bitmap. (Implementing this was trivial if slightly silly.)
|
|
*/
|
|
class ReformatJEQSHR : public ReformatSHR {
|
|
public:
|
|
ReformatJEQSHR(void) {}
|
|
virtual ~ReformatJEQSHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
enum { kExpectedLen = 32288 };
|
|
SHRScreen fScreen;
|
|
};
|
|
|
|
|
|
/*
|
|
* Reformat a Paintworks SHR graphic ($c0/0000) into a bitmap.
|
|
*/
|
|
class ReformatPaintworksSHR : public ReformatSHR {
|
|
public:
|
|
ReformatPaintworksSHR(void) {}
|
|
virtual ~ReformatPaintworksSHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
enum { kMinSize = 223 };
|
|
//SHRScreen fScreen;
|
|
};
|
|
|
|
|
|
/*
|
|
* Reformat a packed SHR graphic ($c0/0001) into a bitmap.
|
|
*/
|
|
class ReformatPackedSHR : public ReformatSHR {
|
|
public:
|
|
ReformatPackedSHR(void) {}
|
|
virtual ~ReformatPackedSHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
SHRScreen fScreen;
|
|
};
|
|
|
|
/*
|
|
* Reformat an Apple-Preferred Format SHR graphic ($c0/0002) into a bitmap.
|
|
*
|
|
* The graphic could be a standard SHR image, a larger or smaller than normal
|
|
* SHR image, or a 3200-color image.
|
|
*/
|
|
class ReformatAPFSHR : public ReformatSHR {
|
|
public:
|
|
ReformatAPFSHR(void) : fNonStandard(false), fPixelStore(NULL),
|
|
fSCBStore(NULL) {}
|
|
virtual ~ReformatAPFSHR(void) {
|
|
if (fPixelStore != NULL && fPixelStore != fScreen.pixels)
|
|
delete[] fPixelStore;
|
|
if (fSCBStore != NULL && fSCBStore != fScreen.scb)
|
|
delete[] fSCBStore;
|
|
}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
int UnpackMain(const uint8_t* srcPtr, long srcLen);
|
|
int UnpackMultipal(uint8_t* dstPtr, const uint8_t* srcPtr, long srcLen);
|
|
void UnpackNote(const uint8_t* srcPtr, long srcLen);
|
|
|
|
/* use this for standard-sized images */
|
|
SHRScreen fScreen;
|
|
|
|
/* set for non-standard images */
|
|
bool fNonStandard;
|
|
|
|
/* use this for non-standard-sized images */
|
|
uint8_t* fPixelStore;
|
|
uint8_t* fSCBStore;
|
|
int fNumScanLines; // #of scan lines in image
|
|
int fPixelsPerScanLine;
|
|
int fPixelBytesPerLine;
|
|
int fOutputWidth;
|
|
int fOutputHeight; // scan lines * 2
|
|
};
|
|
|
|
/*
|
|
* Reformat a 3200-color SHR graphic into a bitmap.
|
|
*/
|
|
class Reformat3200SHR : public ReformatSHR {
|
|
public:
|
|
Reformat3200SHR(void) {}
|
|
virtual ~Reformat3200SHR(void) {}
|
|
|
|
// alternate construction, used by APFSHR
|
|
Reformat3200SHR(SHRScreen* pScreen, uint8_t* multiPal) {
|
|
memcpy(&fScreen, pScreen, sizeof(fScreen));
|
|
memcpy(fExtColorTable, multiPal, sizeof(fExtColorTable));
|
|
}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
MyDIBitmap* SHR3200ToBitmap24(void);
|
|
|
|
protected:
|
|
enum {
|
|
kExtNumColorTables = kNumLines,
|
|
kExtTotalSize = 38400,
|
|
};
|
|
|
|
SHRScreen fScreen; // only "pixels" is valid
|
|
|
|
/* this holds the 200 color tables, with the entries switched to normal */
|
|
uint8_t fExtColorTable[kExtNumColorTables *
|
|
kNumEntriesPerColorTable * kColorTableEntrySize];
|
|
};
|
|
|
|
/*
|
|
* Reformat a packed 3200-color SHR graphic.
|
|
*/
|
|
class Reformat3201SHR : public Reformat3200SHR {
|
|
public:
|
|
Reformat3201SHR(void) {}
|
|
virtual ~Reformat3201SHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
};
|
|
|
|
|
|
/*
|
|
* Generic DreamGrafix code.
|
|
*/
|
|
class DreamGrafix {
|
|
public:
|
|
DreamGrafix(void) : fWidth(0), fHeight(0), fNumColors(0) {}
|
|
~DreamGrafix(void) {}
|
|
|
|
/*
|
|
* Scan the file. If it's a DreamGrafix image, extract values from the
|
|
* header fields and return "true".
|
|
*/
|
|
bool ScanDreamGrafix(ReformatHolder* pHolder);
|
|
|
|
/*
|
|
* Unpack a DreamGrafix SHR image compressed with LZW.
|
|
*/
|
|
bool UnpackDG(const uint8_t* srcBuf, long srcLen,
|
|
ReformatSHR::SHRScreen* pScreen, uint8_t* extColorTable);
|
|
|
|
int fWidth;
|
|
int fHeight;
|
|
int fNumColors;
|
|
|
|
private:
|
|
static int UnpackLZW(const uint8_t* srcBuf, long srcLen,
|
|
uint8_t* dstBuf, long dstLen);
|
|
enum { kHeaderOffset = 17 };
|
|
};
|
|
|
|
/*
|
|
* Reformat a DreamGrafix 256-color SHR graphic.
|
|
*/
|
|
class ReformatDG256SHR : public ReformatSHR {
|
|
public:
|
|
ReformatDG256SHR(void) {}
|
|
virtual ~ReformatDG256SHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
DreamGrafix fDG;
|
|
SHRScreen fScreen;
|
|
};
|
|
|
|
/*
|
|
* Reformat a DreamGrafix 3200-color SHR graphic.
|
|
*/
|
|
class ReformatDG3200SHR : public Reformat3200SHR {
|
|
public:
|
|
ReformatDG3200SHR(void) {}
|
|
virtual ~ReformatDG3200SHR(void) {}
|
|
|
|
virtual void Examine(ReformatHolder* pHolder) override;
|
|
virtual int Process(const ReformatHolder* pHolder,
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
ReformatOutput* pOutput) override;
|
|
|
|
private:
|
|
DreamGrafix fDG;
|
|
};
|
|
|
|
#endif /*REFORMAT_SUPERHIRES_H*/
|