Browse Source

Using image data from PSD instead of manually flattening

Brian Fiete 5 years ago
parent
commit
8aa3e8ff22

+ 29 - 3
BeefTools/ImgCreate/ImgCreate.cpp

@@ -159,13 +159,39 @@ int main()
 					layerIndices.insert(layerIndices.begin(), layerIdx);
 					layerIndices.insert(layerIndices.begin(), layerIdx);
 			}
 			}
 			
 			
-			imageData = reader.MergeLayers(NULL, layerIndices, NULL);
+			imageData = reader.ReadImageData();
+			if (imageData == NULL)
+			{
+				ImageData* rawImageData = reader.MergeLayers(NULL, layerIndices, NULL);;
+				if ((rawImageData->mX == 0) && (rawImageData->mY == 0) &&
+					(rawImageData->mWidth == reader.mWidth) &&
+					(rawImageData->mHeight == reader.mHeight))
+				{
+					imageData = rawImageData;
+				}
+				else
+				{
+					imageData = new ImageData();
+					imageData->CreateNew(reader.mWidth, reader.mHeight);
+					imageData->CopyFrom(rawImageData, 0, 0);
+					delete rawImageData;
+				}
+			}
+// 			else
+// 			{
+// 				PNGData pngData;
+// 				pngData.mWidth = imageData->mWidth;
+// 				pngData.mHeight = imageData->mHeight;
+// 				pngData.mBits = imageData->mBits;
+// 				pngData.WriteToFile("c:\\temp\\test.png");
+// 				pngData.mBits = NULL;
+// 			}
 		}
 		}
 	}
 	}
 
 
 	int numCols = baseWidth / 20;
 	int numCols = baseWidth / 20;
 	int numRows = baseHeight / 20;
 	int numRows = baseHeight / 20;
-
+	
 	auto _HasImage = [&](int col, int row, int pass, int size)
 	auto _HasImage = [&](int col, int row, int pass, int size)
 	{
 	{
 		int scale = 1 << size;
 		int scale = 1 << size;
@@ -267,7 +293,7 @@ int main()
 		for (int row = 0; row < numRows; row++)		
 		for (int row = 0; row < numRows; row++)		
 		{
 		{
 			for (int col = 0; col < numCols; col++)
 			for (int col = 0; col < numCols; col++)
-			{
+			{				
 				int srcPass = 0;
 				int srcPass = 0;
 				int srcSize = size;
 				int srcSize = size;
 
 

+ 20 - 0
BeefySysLib/img/ImageData.cpp

@@ -61,6 +61,26 @@ void ImageData::CreateNew(int width, int height, bool clear)
 		memset(mBits, 0, mWidth*mHeight*sizeof(uint32));
 		memset(mBits, 0, mWidth*mHeight*sizeof(uint32));
 }
 }
 
 
+void ImageData::CopyFrom(ImageData* img, int x, int y)
+{
+	int destStartX = BF_MAX(x + img->mX - mX, 0);
+	int destStartY = BF_MAX(y + img->mY - mY, 0);
+
+	int destEndX = BF_MIN(x + img->mX - mX + img->mWidth, mWidth);
+	int destEndY = BF_MIN(y + img->mY - mY + img->mHeight, mHeight);
+
+	int srcXOfs = -x - img->mX;
+	int srcYOfs = -y - img->mY;
+
+	for (int y = destStartY; y < destEndY; y++)
+	{
+		for (int x = destStartX; x < destEndX; x++)
+		{
+			mBits[x + y * mWidth] = img->mBits[(x + srcXOfs) + (y + srcYOfs)*img->mWidth];
+		}
+	}
+}
+
 void ImageData::Fill(uint32 color)
 void ImageData::Fill(uint32 color)
 {
 {
 	int size = mWidth*mHeight;
 	int size = mWidth*mHeight;

+ 2 - 1
BeefySysLib/img/ImageData.h

@@ -39,9 +39,10 @@ public:
 	void					SwapRAndB();
 	void					SwapRAndB();
 	void					CreateNew(int x, int y, int width, int height, bool clear = true);
 	void					CreateNew(int x, int y, int width, int height, bool clear = true);
 	void					CreateNew(int width, int height, bool clear = true);
 	void					CreateNew(int width, int height, bool clear = true);
+	void					CopyFrom(ImageData* img, int x, int y);
 	void					Fill(uint32 color);
 	void					Fill(uint32 color);
 	virtual ImageData*		Duplicate();
 	virtual ImageData*		Duplicate();
-	void					SetSrcData(uint8* data, int dataLen);
+	void					SetSrcData(uint8* data, int dataLen);	
 	virtual bool			LoadFromFile(const StringImpl& path);
 	virtual bool			LoadFromFile(const StringImpl& path);
 	virtual	bool			ReadData() { return false; }
 	virtual	bool			ReadData() { return false; }
 	virtual void			PremultiplyAlpha();
 	virtual void			PremultiplyAlpha();

+ 92 - 0
BeefySysLib/img/PSDReader.cpp

@@ -172,6 +172,7 @@ PSDReader::PSDReader()
 	mFS = NULL;
 	mFS = NULL;
 	mGlobalAltitude = 0;
 	mGlobalAltitude = 0;
 	mGlobalAngle = 30;
 	mGlobalAngle = 30;
+	mImageDataSectStart = -1;
 }
 }
 
 
 PSDReader::~PSDReader()
 PSDReader::~PSDReader()
@@ -1398,9 +1399,100 @@ bool PSDReader::Init(const StringImpl& fileName)
 	mFS->SetPos(startPos + layerAndMaskLen);
 	mFS->SetPos(startPos + layerAndMaskLen);
 	pos = mFS->GetPos();
 	pos = mFS->GetPos();
 
 
+	mImageDataSectStart = mFS->GetPos();	
+	
 	return true;
 	return true;
 }
 }
 
 
+ImageData* PSDReader::ReadImageData()
+{
+	mFS->SetPos(mImageDataSectStart);
+
+	int compression = mFS->ReadInt16();
+	if ((compression != 0) && (compression != 1))
+		return NULL;	
+
+	ImageData* imageData = new ImageData();
+	imageData->CreateNew(mWidth, mHeight);
+	if (mChannels < 4)
+		imageData->Fill(0xFF000000);
+
+	int16** rowLengths = NULL;
+	int horz = mWidth;
+	int vert = mHeight;
+	int aSize = horz*vert;
+
+	if (compression == 1)
+	{
+		rowLengths = new int16*[mChannels];		
+		for (int channel = 0; channel < mChannels; channel++)
+		{
+			rowLengths[channel] = new int16[vert];
+			for (int aY = 0; aY < vert; aY++)
+				rowLengths[channel][aY] = mFS->ReadInt16();
+		}
+	}
+
+	for (int channel = 0; channel < mChannels; channel++)
+	{
+		int shift = channel * 8;
+		// 		if (channel == mC + 1)
+		// 			shift = 24;
+
+		if (channel == 4)
+			break;
+
+		if (compression == 0)
+		{
+			for (int pos = 0; pos < aSize; pos++)
+				imageData->mBits[pos] |= ((uint32)(uint8)mFS->ReadInt8()) << shift;
+		}
+		else
+		{						
+			for (int aY = 0; aY < vert; aY++)
+			{
+				int pos = aY * horz;
+				int readSize = rowLengths[channel][aY];
+
+				while (readSize > 0)
+				{
+					int chunkSize = mFS->ReadInt8();
+					readSize--;
+					if (chunkSize >= 0)
+					{
+						// String of literal data
+						chunkSize++;
+						readSize -= chunkSize;
+						while (chunkSize > 0)
+						{
+							imageData->mBits[pos++] |= ((uint32)(uint8)mFS->ReadInt8()) << shift;
+							chunkSize--;
+						}
+					}
+					else if (chunkSize > -128)
+					{
+						// One byte repeated
+						chunkSize = 1 - chunkSize;
+						uint32 aData = ((uint32)(uint8)mFS->ReadInt8()) << shift;
+						readSize--;
+						while (chunkSize > 0)
+						{
+							imageData->mBits[pos++] |= aData;
+							chunkSize--;
+						}
+					}
+				}
+			}
+		}
+	}
+	if (rowLengths != NULL)
+	{
+		for (int i = 0; i < mChannels; i++)
+			delete rowLengths[i];
+	}
+	return imageData;
+}
+
 Texture* PSDReader::LoadLayerTexture(int layerIdx, int* ofsX, int* ofsY) // -1 = composited image
 Texture* PSDReader::LoadLayerTexture(int layerIdx, int* ofsX, int* ofsY) // -1 = composited image
 {
 {
 	if ((layerIdx < 0) || (layerIdx >= (int) mPSDLayerInfoVector.size()))
 	if ((layerIdx < 0) || (layerIdx >= (int) mPSDLayerInfoVector.size()))

+ 3 - 1
BeefySysLib/img/PSDReader.h

@@ -191,12 +191,13 @@ public:
 	int						mGlobalAltitude;
 	int						mGlobalAltitude;
 
 
 	int						mChannels;	
 	int						mChannels;	
+	int						mImageDataSectStart;
 
 
 	PSDLayerInfoVector		mPSDLayerInfoVector;
 	PSDLayerInfoVector		mPSDLayerInfoVector;
 	PSDPatternMap			mPSDPatternMap;
 	PSDPatternMap			mPSDPatternMap;
 
 
 public:
 public:
-	String				ReadIdString();
+	String					ReadIdString();
 	void					ReadPSDValue(PSDValue* value);
 	void					ReadPSDValue(PSDValue* value);
 	void					ReadPSDDescriptor(PSDDescriptor* descriptor);
 	void					ReadPSDDescriptor(PSDDescriptor* descriptor);
 	void					ReadEffectColor(PSDDescriptor* colorDesc, uint32* color);
 	void					ReadEffectColor(PSDDescriptor* colorDesc, uint32* color);
@@ -215,6 +216,7 @@ public:
 
 
 	bool					Init(const StringImpl& fileName);
 	bool					Init(const StringImpl& fileName);
 
 
+	ImageData*				ReadImageData();
 	Texture*				LoadLayerTexture(int layerIdx, int* ofsX, int* ofsY); // -1 = composited image
 	Texture*				LoadLayerTexture(int layerIdx, int* ofsX, int* ofsY); // -1 = composited image
 	ImageData*				MergeLayers(PSDLayerInfo* group, const std::vector<int>& layerIndices, ImageData* bottomImage);	
 	ImageData*				MergeLayers(PSDLayerInfo* group, const std::vector<int>& layerIndices, ImageData* bottomImage);	
 	Texture*				LoadMergedLayerTexture(const std::vector<int>& layerIndices, int* ofsX, int* ofsY);
 	Texture*				LoadMergedLayerTexture(const std::vector<int>& layerIndices, int* ofsX, int* ofsY);

BIN
IDE/dist/images/ImgCreate.exe