2007-03-27 17:47:10 +00:00
|
|
|
/*
|
|
|
|
* CiderPress
|
|
|
|
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
|
|
|
* See the file LICENSE for distribution terms.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* Reformat Print Shop graphics.
|
|
|
|
*
|
|
|
|
* The "image editor" in Print Shop GS shows a nearly square image. It looks
|
|
|
|
* like it doubles with width and triples the height, resulting in a
|
|
|
|
* 176x156 image. We could do that here, but that would make it harder to
|
|
|
|
* manipulate the basic pixels if a different aspect ratio were desired.
|
|
|
|
* (May want to make that an option someday.)
|
|
|
|
*/
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "PrintShop.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Decide whether or not we want to handle this file.
|
|
|
|
*/
|
2014-11-25 22:34:14 +00:00
|
|
|
void ReformatPrintShop::Examine(ReformatHolder* pHolder)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
ReformatHolder::ReformatApplies applies = ReformatHolder::kApplicNot;
|
|
|
|
long fileType = pHolder->GetFileType();
|
|
|
|
long auxType = pHolder->GetAuxType();
|
|
|
|
long length = pHolder->GetSourceLen(ReformatHolder::kPartData);
|
|
|
|
bool relaxed;
|
|
|
|
|
|
|
|
relaxed = pHolder->GetOption(ReformatHolder::kOptRelaxGfxTypeCheck) != 0;
|
|
|
|
|
|
|
|
if (length == 576 && fileType == kTypeBIN) {
|
|
|
|
/* PrintShop monochrome */
|
|
|
|
if (auxType == 0x4800 || auxType == 0x5800 ||
|
|
|
|
auxType == 0x6800 || auxType == 0x7800)
|
|
|
|
applies = ReformatHolder::kApplicYes;
|
|
|
|
else
|
|
|
|
applies = ReformatHolder::kApplicMaybe; // below monitor listing
|
|
|
|
} else if (length == 1716) {
|
|
|
|
/* PrintShop GS color */
|
|
|
|
if (fileType == 0xf8) {
|
|
|
|
if (auxType == 0xc323)
|
|
|
|
applies = ReformatHolder::kApplicYes;
|
|
|
|
else
|
|
|
|
applies = ReformatHolder::kApplicProbably;
|
|
|
|
} else if (fileType == kTypeBIN && relaxed)
|
|
|
|
applies = ReformatHolder::kApplicMaybe;
|
|
|
|
} else if (length == 572) {
|
|
|
|
/* PrintShop GS monochrome */
|
|
|
|
if (fileType == 0xf8 && auxType == 0xc313)
|
|
|
|
applies = ReformatHolder::kApplicYes;
|
|
|
|
}
|
|
|
|
|
|
|
|
pHolder->SetApplic(ReformatHolder::kReformatPrintShop, applies,
|
|
|
|
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert Print Shop clip art into a DIB.
|
|
|
|
*/
|
2014-11-25 22:34:14 +00:00
|
|
|
int ReformatPrintShop::Process(const ReformatHolder* pHolder,
|
2014-11-04 00:26:53 +00:00
|
|
|
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
|
|
|
|
ReformatOutput* pOutput)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-18 05:13:13 +00:00
|
|
|
MyDIBitmap* pDib = NULL;
|
2014-11-21 02:10:18 +00:00
|
|
|
const uint8_t* srcBuf = pHolder->GetSourceBuf(part);
|
2014-11-04 00:26:53 +00:00
|
|
|
long srcLen = pHolder->GetSourceLen(part);
|
|
|
|
|
|
|
|
if (srcLen == 572 || srcLen == 576) {
|
|
|
|
pDib = ConvertBW(srcBuf);
|
|
|
|
} else if (srcLen == 1716) {
|
|
|
|
pDib = ConvertColor(srcBuf);
|
|
|
|
} else {
|
2014-11-18 21:05:15 +00:00
|
|
|
LOGI("PS shouldn't be here (len=%ld)", srcLen);
|
2014-11-04 00:26:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-11-18 05:13:13 +00:00
|
|
|
if (pDib == NULL) {
|
2014-11-18 21:05:15 +00:00
|
|
|
LOGI("DIB creation failed");
|
2014-11-04 00:26:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetResultBuffer(pOutput, pDib);
|
|
|
|
return 0;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert a B&W "classic" Print Shop graphic.
|
|
|
|
*
|
|
|
|
* This does a "straight" conversion without half-pixel shifting
|
|
|
|
* or other monkey business.
|
|
|
|
*
|
|
|
|
* The file is a linear 1-bit 88x52 image, with four extra bytes of data
|
|
|
|
* at the end.
|
|
|
|
*/
|
2014-11-25 22:34:14 +00:00
|
|
|
MyDIBitmap* ReformatPrintShop::ConvertBW(const uint8_t* srcBuf)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
MyDIBitmap* pDib = new MyDIBitmap;
|
2014-11-21 02:10:18 +00:00
|
|
|
uint8_t* outBuf;
|
|
|
|
uint8_t* ptr;
|
2014-11-04 00:26:53 +00:00
|
|
|
int pitch;
|
|
|
|
int x, y;
|
|
|
|
|
2014-11-18 05:13:13 +00:00
|
|
|
if (pDib == NULL)
|
|
|
|
return NULL;
|
2014-11-04 00:26:53 +00:00
|
|
|
|
|
|
|
RGBQUAD colorConv[2];
|
|
|
|
colorConv[0].rgbRed = colorConv[0].rgbGreen = colorConv[0].rgbBlue = 255;
|
|
|
|
colorConv[1].rgbRed = colorConv[1].rgbGreen = colorConv[1].rgbBlue = 0;
|
|
|
|
colorConv[0].rgbReserved = colorConv[1].rgbReserved = 0;
|
|
|
|
|
2014-11-21 02:10:18 +00:00
|
|
|
outBuf = (uint8_t*) pDib->Create(kWidth, kHeight, 1, 2);
|
2014-11-18 05:13:13 +00:00
|
|
|
if (outBuf == NULL) {
|
2014-11-04 00:26:53 +00:00
|
|
|
delete pDib;
|
2014-11-18 05:13:13 +00:00
|
|
|
pDib = NULL;
|
2014-11-04 00:26:53 +00:00
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
pDib->SetColorTable(colorConv);
|
|
|
|
|
|
|
|
pitch = pDib->GetPitch();
|
|
|
|
|
|
|
|
/* build it in standard upside-down Windows format */
|
|
|
|
for (y = kHeight-1; y >= 0; y--) {
|
|
|
|
ptr = outBuf + y * pitch;
|
|
|
|
for (x = 0; x < kWidth/8; x++)
|
|
|
|
*ptr++ = *srcBuf++;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
return pDib;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The format is similar to the B&W version, but instead of one bitmap
|
|
|
|
* there are three. They're sorta-kinda CMY:
|
|
|
|
*
|
|
|
|
* >[...] There are 3 bit maps for the graphic. The
|
|
|
|
* >first is yellow, the second is magenta and the third is cyan. The other
|
|
|
|
* >colors are from combinations. Yellow and magenta is orange. Yellow and cyan
|
|
|
|
* >is green. Magenta and cyan are purple. All three is black.
|
|
|
|
*
|
|
|
|
* It appears, based on running Print Shop GS in an emulator, that "cyan"
|
|
|
|
* is actually 100% blue and "magenta" is 100% red. The values in the color
|
|
|
|
* table below come from a screen capture of KEGS.
|
|
|
|
*/
|
2014-11-25 22:34:14 +00:00
|
|
|
MyDIBitmap* ReformatPrintShop::ConvertColor(const uint8_t* srcBuf)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
MyDIBitmap* pDib = new MyDIBitmap;
|
2014-11-21 02:10:18 +00:00
|
|
|
uint8_t* outBuf;
|
|
|
|
uint8_t* ptr;
|
|
|
|
uint8_t outVal;
|
|
|
|
uint16_t yellow, magenta, cyan;
|
2014-11-04 00:26:53 +00:00
|
|
|
int pitch;
|
|
|
|
int x, y, bit;
|
|
|
|
static const RGBQUAD kColorConv[8] = {
|
|
|
|
/* blue, green, red, reserved YMC */
|
|
|
|
{ 0xff, 0xff, 0xff }, // 000 white
|
|
|
|
{ 0xff, 0x00, 0x00 }, // 001 cyan (blue)
|
|
|
|
{ 0x00, 0x00, 0xff }, // 010 magenta (red)
|
|
|
|
{ 0xcc, 0x00, 0xcc }, // 011 purple
|
|
|
|
{ 0x00, 0xff, 0xff }, // 100 yellow
|
|
|
|
{ 0x00, 0xff, 0x00 }, // 101 green
|
|
|
|
{ 0x00, 0x66, 0xff }, // 110 orange
|
|
|
|
{ 0x00, 0x00, 0x00 }, // 111 black
|
|
|
|
};
|
|
|
|
|
2014-11-18 05:13:13 +00:00
|
|
|
if (pDib == NULL)
|
|
|
|
return NULL;
|
2014-11-04 00:26:53 +00:00
|
|
|
|
2014-11-21 02:10:18 +00:00
|
|
|
outBuf = (uint8_t*) pDib->Create(kWidth, kHeight, 4, 8);
|
2014-11-18 05:13:13 +00:00
|
|
|
if (outBuf == NULL) {
|
2014-11-04 00:26:53 +00:00
|
|
|
delete pDib;
|
2014-11-18 05:13:13 +00:00
|
|
|
pDib = NULL;
|
2014-11-04 00:26:53 +00:00
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
pDib->SetColorTable(kColorConv);
|
|
|
|
|
|
|
|
pitch = pDib->GetPitch();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build it in standard upside-down Windows format.
|
|
|
|
*
|
|
|
|
* We pre-shift the yellow/magenta/cyan values into offsetting positions
|
|
|
|
* to save ourselves a shift each time through the loop.
|
|
|
|
*/
|
|
|
|
for (y = kHeight-1; y >= 0; y--) {
|
|
|
|
ptr = outBuf + y * pitch;
|
|
|
|
for (x = 0; x < kWidth/8; x++) {
|
|
|
|
yellow = *srcBuf << 2;
|
|
|
|
magenta = *(srcBuf + (kWidth/8)*kHeight) << 1;
|
|
|
|
cyan = *(srcBuf + (kWidth/8)*kHeight *2);
|
|
|
|
|
|
|
|
/* each 3-bit combo turns into a 4-bit index, 2 per output byte */
|
|
|
|
for (bit = 0; bit < 4; bit++) {
|
|
|
|
outVal = ((yellow & 0x200) | (magenta & 0x100) | (cyan & 0x80)) >> 3;
|
|
|
|
yellow <<= 1;
|
|
|
|
magenta <<= 1;
|
|
|
|
cyan <<= 1;
|
|
|
|
outVal |= ((yellow & 0x200) | (magenta & 0x100) | (cyan & 0x80)) >> 7;
|
|
|
|
yellow <<= 1;
|
|
|
|
magenta <<= 1;
|
|
|
|
cyan <<= 1;
|
|
|
|
*ptr++ = outVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
srcBuf++;
|
|
|
|
}
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
return pDib;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|