mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-22 18:35:30 +00:00
141 lines
5.4 KiB
C#
141 lines
5.4 KiB
C#
/* Copyright (c) 2022-present miku-666
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any damages
|
|
* arising from the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
*
|
|
* 1.The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software. If you use this software
|
|
* in a product, an acknowledgment in the product documentation would be
|
|
* appreciated but is not required.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
**/
|
|
using System;
|
|
using System.IO;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using OMI;
|
|
|
|
namespace PckStudio.Core.IO.TGA
|
|
{
|
|
internal class TGAWriter
|
|
{
|
|
private Bitmap _bitmap;
|
|
private int extensionDataOffset = 0;
|
|
|
|
public TGAWriter()
|
|
{
|
|
}
|
|
|
|
private void WriteHeader(EndiannessAwareBinaryWriter writer)
|
|
{
|
|
writer.Write(new byte[]
|
|
{
|
|
0, // header.Id.Length
|
|
0, // colormap type
|
|
(byte)TGADataTypeCode.RGB
|
|
});
|
|
writer.Write(0); // Colormap.Origin
|
|
writer.Write(0); // Colormap.Length
|
|
writer.Write(0); // Colormap.Depth
|
|
writer.Write(0); // Origin.X
|
|
writer.Write(0); // Origin.Y
|
|
writer.Write(_bitmap.Width);
|
|
writer.Write(_bitmap.Height);
|
|
writer.Write(32); // BitsPerPixel
|
|
writer.Write(8); // ImageDescriptor
|
|
}
|
|
|
|
private void WriteImage(EndiannessAwareBinaryWriter writer)
|
|
{
|
|
_bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
|
BitmapData bitmapData = _bitmap.LockBits(
|
|
new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
|
|
ImageLockMode.ReadOnly,
|
|
PixelFormat.Format32bppArgb);
|
|
|
|
byte[] buffer = new byte[_bitmap.Width * _bitmap.Height * 4];
|
|
Marshal.Copy(bitmapData.Scan0, buffer, 0, _bitmap.Width * _bitmap.Height * 4);
|
|
writer.Write(buffer);
|
|
}
|
|
|
|
private void WriteFooter(EndiannessAwareBinaryWriter writer)
|
|
{
|
|
writer.Write(extensionDataOffset); // extensionDataOffset
|
|
writer.Write(0); // developerAreaDataOffset
|
|
writer.WriteString(TGAFooter.Signature);
|
|
writer.Write((byte)0x2E);
|
|
writer.Write((byte)0x00);
|
|
}
|
|
|
|
private void WriteExtensionData(EndiannessAwareBinaryWriter writer)
|
|
{
|
|
extensionDataOffset = Convert.ToInt32(writer.BaseStream.Position);
|
|
TGAExtentionData extentionData = TGAExtentionData.Create();
|
|
writer.Write(TGAExtentionData.ExtensionSize);
|
|
// Author Name
|
|
writer.WriteString(extentionData.AuthorName, 41);
|
|
// Author Comment
|
|
writer.WriteString(extentionData.AuthorComment, 324);
|
|
// Timestamp
|
|
writer.Write((short)extentionData.TimeStamp.Month);
|
|
writer.Write((short)extentionData.TimeStamp.Day);
|
|
writer.Write((short)extentionData.TimeStamp.Year);
|
|
writer.Write((short)extentionData.TimeStamp.Hour);
|
|
writer.Write((short)extentionData.TimeStamp.Minute);
|
|
writer.Write((short)extentionData.TimeStamp.Second);
|
|
// Job id
|
|
writer.WriteString(extentionData.JobID, 41);
|
|
// Job time
|
|
writer.Write((short)extentionData.JobTime.Hours);
|
|
writer.Write((short)extentionData.JobTime.Minutes);
|
|
writer.Write((short)extentionData.JobTime.Seconds);
|
|
// Software Id
|
|
writer.WriteString(extentionData.SoftwareID, 41);
|
|
// Software version
|
|
writer.Write(extentionData.SoftwareVersion, 0, 3);
|
|
// Key color
|
|
writer.Write(extentionData.KeyColor);
|
|
// Pixel aspect ratio
|
|
writer.Write(extentionData.PixelAspectRatio);
|
|
// Gamma value
|
|
writer.Write(extentionData.GammaValue);
|
|
// Color correction offset
|
|
writer.Write(extentionData.ColorCorrectionOffset);
|
|
// Postage stamp offset
|
|
writer.Write(extentionData.PostageStampOffset);
|
|
// Scan line offset
|
|
writer.Write(extentionData.ScanLineOffset);
|
|
// Attributes type
|
|
writer.Write(extentionData.AttributesType);
|
|
}
|
|
|
|
public void WriteToStream(Stream stream, Image image)
|
|
{
|
|
_bitmap = new Bitmap(image);
|
|
using (var writer = new EndiannessAwareBinaryWriter(stream, Encoding.ASCII, leaveOpen: true, ByteOrder.LittleEndian))
|
|
{
|
|
WriteHeader(writer);
|
|
WriteImage(writer);
|
|
WriteExtensionData(writer);
|
|
WriteFooter(writer);
|
|
}
|
|
}
|
|
|
|
public void WriteToFile(string filename, Image image)
|
|
{
|
|
using (FileStream fs = File.OpenWrite(filename))
|
|
{
|
|
WriteToStream(fs, image);
|
|
}
|
|
}
|
|
}
|
|
}
|