コード例 #1
0
ファイル: PSPFile.cs プロジェクト: 0xC0000054/pdn-pspformat
        private void LoadPSPFile(Stream input)
        {
            byte[] sigBytes = new byte[32];

            input.ProperRead(sigBytes, 0, sigBytes.Length);

            if (!CheckSig(sigBytes))
            {
                throw new FormatException(Properties.Resources.InvalidPSPFile);
            }

            using (BufferedBinaryReader reader = new BufferedBinaryReader(input))
            {
                this.fileHeader = new FileHeader(reader);

                while (reader.Position < reader.Length)
                {
                    uint blockSig = reader.ReadUInt32();
                    if (blockSig != PSPConstants.blockIdentifier)
                    {
                        throw new FormatException(Properties.Resources.InvalidBlockSignature);
                    }
                    PSPBlockID blockID            = (PSPBlockID)reader.ReadUInt16();
                    uint       initialBlockLength = this.fileHeader.Major <= PSPConstants.majorVersion5 ? reader.ReadUInt32() : 0;
                    uint       blockLength        = reader.ReadUInt32();

                    switch (blockID)
                    {
                    case PSPBlockID.ImageAttributes:
                        this.imageAttributes = new GeneralImageAttributes(reader, this.fileHeader.Major);
                        break;

                    case PSPBlockID.Creator:
                        this.creator = new CreatorBlock(reader, blockLength);
                        break;

                    case PSPBlockID.ColorPalette:
                        this.globalPalette = new ColorPaletteBlock(reader, this.fileHeader.Major);
                        break;

                    case PSPBlockID.LayerStart:
                        this.layerBlock = new LayerBlock(reader, this.imageAttributes, this.fileHeader.Major);
                        break;

                    case PSPBlockID.ExtendedData:
                        this.extData = new ExtendedDataBlock(reader, blockLength);
                        break;

#if DEBUG
                    case PSPBlockID.CompositeImageBank:
                        this.compImage = new CompositeImageBlock(reader, this.fileHeader.Major);
                        break;
#endif
                    default:
                        reader.Position += blockLength;
                        break;
                    }
                }
            }
        }
コード例 #2
0
ファイル: PSPFile.cs プロジェクト: 0xC0000054/pdn-pspformat
 public PSPFile()
 {
     this.fileHeader      = null;
     this.imageAttributes = null;
     this.extData         = null;
     this.creator         = null;
     this.compImage       = null;
     this.globalPalette   = null;
     this.layerBlock      = null;
     this.v5Thumbnail     = null;
 }
コード例 #3
0
ファイル: PSPFile.cs プロジェクト: 0xC0000054/pdn-pspformat
        public void Save(Document input, Stream output, CompressionFormats format, Surface scratchSurface, ushort majorVersion, ProgressEventHandler callback)
        {
            if (majorVersion == PSPConstants.majorVersion5 && input.Layers.Count > 64)
            {
                throw new FormatException(string.Format(Properties.Resources.MaxLayersFormat, 64));
            }
            else if ((majorVersion == PSPConstants.majorVersion6 || majorVersion == PSPConstants.majorVersion7) && input.Layers.Count > 100)
            {
                throw new FormatException(string.Format(Properties.Resources.MaxLayersFormat, 100));
            }

            using (BinaryWriterEx writer = new BinaryWriterEx(output, false))
            {
                this.fileHeader      = new FileHeader(majorVersion);
                this.imageAttributes = new GeneralImageAttributes(
                    input.Width,
                    input.Height,
                    CompressionFromTokenFormat(format),
                    0,
                    input.Layers.Count,
                    majorVersion);
                switch (input.DpuUnit)
                {
                case MeasurementUnit.Centimeter:
                    this.imageAttributes.ResValue = input.DpuX;
                    this.imageAttributes.ResUnit  = ResolutionMetric.Centimeter;
                    break;

                case MeasurementUnit.Inch:
                    this.imageAttributes.ResValue = input.DpuX;
                    this.imageAttributes.ResUnit  = ResolutionMetric.Inch;
                    break;
                }

                this.totalProgress = 0;
                this.doneProgress  = 0;

                bool flatImage = true;
                foreach (Layer item in input.Layers)
                {
                    BitmapLayer layer = (BitmapLayer)item;

                    Rectangle rect = PSPUtil.GetImageSaveRectangle(layer.Surface);

                    if (!rect.IsEmpty)
                    {
                        if (LayerHasTransparency(layer.Surface, rect))
                        {
                            this.totalProgress += 4;
                            flatImage           = false;
                        }
                        else
                        {
                            this.totalProgress += 3;
                        }
                    }
                }

                if (flatImage)
                {
                    this.imageAttributes.SetGraphicContentFlag(PSPGraphicContents.FlatImage);
                }

                if (majorVersion > PSPConstants.majorVersion5)
                {
                    CreateCompositeImageBlock(input, scratchSurface, callback, majorVersion);
                }
                else
                {
                    CreateThumbnailBlock(input, scratchSurface, callback, majorVersion);
                }

                int layerCount = input.Layers.Count;

                LayerInfoChunk[]       layerInfoChunks   = new LayerInfoChunk[layerCount];
                LayerBitmapInfoChunk[] layerBitmapChunks = new LayerBitmapInfoChunk[layerCount];

                for (int i = 0; i < layerCount; i++)
                {
                    BitmapLayer layer = (BitmapLayer)input.Layers[i];

                    Rectangle savedBounds = PSPUtil.GetImageSaveRectangle(layer.Surface);

                    LayerInfoChunk infoChunk = new LayerInfoChunk(layer, BlendOptoBlendMode(layer.BlendOp), savedBounds, majorVersion);

                    int channelCount = 3;
                    int bitmapCount  = 1;

                    if (LayerHasTransparency(layer.Surface, savedBounds))
                    {
                        channelCount = 4;
                        bitmapCount  = 2;
                    }

                    LayerBitmapInfoChunk biChunk = new LayerBitmapInfoChunk(bitmapCount, channelCount)
                    {
                        channels = SplitImageChannels(layer.Surface, savedBounds, channelCount, majorVersion, false, callback)
                    };

                    if (majorVersion <= PSPConstants.majorVersion5)
                    {
                        infoChunk.v5BitmapCount  = biChunk.bitmapCount;
                        infoChunk.v5ChannelCount = biChunk.channelCount;
                    }

                    layerInfoChunks[i]   = infoChunk;
                    layerBitmapChunks[i] = biChunk;
                }

                this.layerBlock = new LayerBlock(layerInfoChunks, layerBitmapChunks);

                string creatorData = input.Metadata.GetUserValue(PSPCreatorMetaData);
                if (!string.IsNullOrEmpty(creatorData))
                {
                    this.creator = DeserializeFromBase64 <CreatorBlock>(creatorData);
                }
                else
                {
                    this.creator = new CreatorBlock();
                }

                writer.Write(PSPFileSig);
                this.fileHeader.Save(writer);
                this.imageAttributes.Save(writer);
                this.creator.Save(writer);
                if (this.compImage != null)
                {
                    this.compImage.Save(writer);
                }
                else if (this.v5Thumbnail != null)
                {
                    this.v5Thumbnail.Save(writer);
                }
                this.layerBlock.Save(writer, majorVersion);
            }
        }