public bool IsThumbnailIncluded()
{
return m_bThumbnailFilled; 
} public int GetBitsPerPixel()
{
return m_HeaderInfo.nBitsPerPixel; 
} public int GlobalAngle()
{
return m_nGlobalAngle; 
} public bool IsCopyrighted()
{
return m_bCopyright; 
} public IntPtr GetHBitmap()
{
return m_hBitmap;
} public int GetWidth()
{
return m_HeaderInfo.nWidth;
}

public int GetHeight()
{
return m_HeaderInfo.nHeight;
} public int GetXResolution()
{
return m_ResolutionInfo.hRes;
} public int GetYResolution()
{
return m_ResolutionInfo.vRes;
} public int GetCompression()
{
return m_nCompression;
}

protected bool ReadHeader(FileStream stream)
{
bool bSuccess = false; BinaryReader binReader = new BinaryReader(stream);
try
{
// Set Position to the beginning of the stream.
binReader.BaseStream.Position = 0;
byte [] Signature  = binReader.ReadBytes(4); // always equal 8BPS, do not read file if not
byte [] Version    = binReader.ReadBytes(2); // always equal 1, do not read file if not
byte [] Reserved   = binReader.ReadBytes(6); // must be zero
byte [] Channels   = binReader.ReadBytes(2); // numer of channels including any alpha channels, supported range 1 to 24
byte [] Rows       = binReader.ReadBytes(4); // height in PIXELS, supported range 1 to 30000
byte [] Columns    = binReader.ReadBytes(4); // width in PIXELS, supported range 1 to 30000
byte [] Depth      = binReader.ReadBytes(2); // number of bpp
byte [] Mode       = binReader.ReadBytes(2); // colour mode of the file
// Btmap=0, Grayscale=1, Indexed=2, RGB=3,
// CMYK=4, Multichannel=7, Duotone=8, Lab=9
ASCIIEncoding encoding = new ASCIIEncoding(); if( encoding.GetString(Signature).Equals("8BPS") && Version[1] == 0x01)
{
m_HeaderInfo = new HeaderInfo();  if(SwapBytes(Channels,2)) m_HeaderInfo.nChannels = BitConverter.ToInt16(Channels,0);
if(SwapBytes(Rows,4)) m_HeaderInfo.nHeight = BitConverter.ToInt32(Rows,0);
if(SwapBytes(Columns,4)) m_HeaderInfo.nWidth = BitConverter.ToInt32(Columns,0);
if(SwapBytes(Depth,2)) m_HeaderInfo.nBitsPerPixel = BitConverter.ToInt16(Depth,0);
if(SwapBytes(Mode,2)) m_HeaderInfo.nColourMode = BitConverter.ToInt16(Mode,0); if(m_HeaderInfo.nChannels != -1 && m_HeaderInfo.nHeight != -1 && m_HeaderInfo.nWidth != -1 && m_HeaderInfo.nBitsPerPixel != -1 && m_HeaderInfo.nColourMode != -1) bSuccess = true;
}
}
catch(EndOfStreamException e)
{
System.Windows.Forms.MessageBox.Show("Exception occurs while reading file header: {0}", e.GetType().Name);
} return bSuccess;
} protected bool ReadColourModeData(FileStream stream)
{
bool bSuccess = false;

// Only indexed colour and duotone have colour mode data,
// for all other modes this section is 4 bytes length, the length field is set to zero // For indexed color images, the length will be equal to 768, and the color
// will contain the color table for the image, in non杋nterleaved order. // For duotone images, the color data will contain the duotone specification,
// the format of which is not documented. Other applications that read
// Photoshop files can treat a duotone image as a grayscale image, and just
// preserve the contents of the duotone information when reading and writing
// the file.

BinaryReader binReader = new BinaryReader(stream);
try
{
// Set Position to the beginning of the stream + size of HeaderInfo.
binReader.BaseStream.Position = 26;
byte [] ColorMode  = binReader.ReadBytes(4); int nLength = 0; m_ColorModeData = new ColorModeData();
if(SwapBytes(ColorMode,4)) nLength = BitConverter.ToInt32(ColorMode,0);
m_ColorModeData.nLength = nLength; if(nLength>0)
{
m_ColorModeData.ColourData = new byte[nLength];
m_ColorModeData.ColourData = binReader.ReadBytes(nLength);
}

bSuccess = true;
}
catch(EndOfStreamException e)
{
MessageBox.Show("Exception occurs while reading color mode data: {0}", e.GetType().Name);
} return bSuccess;
}

解决方案 »

  1.   


    protected bool ReadImageResource(FileStream stream)
    {
    bool bSuccess = false;

    BinaryReader binReader = new BinaryReader(stream);
    try
    {
    int nLength = 0; byte [] Length  = binReader.ReadBytes(4); m_ImageResource = new ImageResource();
    m_ResolutionInfo = new ResolutionInfo();
    m_DisplayInfo = new DisplayInfo();
    m_ThumbNail = new ThumbNail();
     
    if(SwapBytes(Length,4)) nLength = BitConverter.ToInt32(Length,0);
    m_ImageResource.nLength = nLength; int nBytesRead = 0;
    int nTotalBytes = m_ImageResource.nLength;
    long nStreamLen = stream.Length; while(stream.Position < nStreamLen && nBytesRead < nTotalBytes)
    {
    m_ImageResource.Reset();
    m_ImageResource.OSType  = binReader.ReadBytes(4);
    nBytesRead += 4; ASCIIEncoding encoding = new ASCIIEncoding();

    if(encoding.GetString(m_ImageResource.OSType).Equals("8BIM"))
    {
    byte [] ID = binReader.ReadBytes(2);
    nBytesRead += 2; if(SwapBytes(ID,2)) m_ImageResource.nID = BitConverter.ToInt16(ID,0); byte SizeOfName = binReader.ReadByte();
    nBytesRead += 1;

    int nSizeOfName = (int)SizeOfName;
    if(nSizeOfName>0)
    {
    if((nSizeOfName % 2)!=0) // must read 1 more byte to make size even
    {
    SizeOfName = binReader.ReadByte();
    nBytesRead += 1;
    }

    m_ImageResource.Name = new byte[nSizeOfName];
    m_ImageResource.Name = binReader.ReadBytes(nSizeOfName);
    nBytesRead += nSizeOfName;
    }

    SizeOfName = binReader.ReadByte();
    nBytesRead += 1; byte [] Size = binReader.ReadBytes(4);
    if(SwapBytes(Size,4)) m_ImageResource.nSize = BitConverter.ToInt32(Size,0);
    nBytesRead += 4; if((m_ImageResource.nSize % 2) != 0) // resource data must be even
    m_ImageResource.nSize++;

    if(m_ImageResource.nSize>0)
    {
    byte [] IntValue = new byte[4];
    byte [] ShortValue = new byte[2]; switch(m_ImageResource.nID)
    {
    case 1005:
    {
    m_bResolutionInfoFilled = true; ShortValue = binReader.ReadBytes(2);
    if(SwapBytes(ShortValue,2)) m_ResolutionInfo.hRes = BitConverter.ToInt16(ShortValue,0);
    nBytesRead += 2;
    IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ResolutionInfo.hResUnit = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4;
    ShortValue = binReader.ReadBytes(2);
    if(SwapBytes(ShortValue,2)) m_ResolutionInfo.widthUnit = BitConverter.ToInt16(ShortValue,0);
    nBytesRead += 2;
    ShortValue = binReader.ReadBytes(2);
    if(SwapBytes(ShortValue,2)) m_ResolutionInfo.vRes = BitConverter.ToInt16(ShortValue,0);
    nBytesRead += 2;
    IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ResolutionInfo.vResUnit = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4;
    ShortValue = binReader.ReadBytes(2);
    if(SwapBytes(ShortValue,2)) m_ResolutionInfo.heightUnit = BitConverter.ToInt16(ShortValue,0);
    nBytesRead += 2;
    }
    break;
    case 1007:
    {
    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_DisplayInfo.ColourSpace = BitConverter.ToInt16(ShortValue,0); for(int n=0; n<4; ++n)
    {
    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_DisplayInfo.Colour[n] = BitConverter.ToInt16(ShortValue,0);
    }

    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_DisplayInfo.Opacity = BitConverter.ToInt16(ShortValue,0);
    if(m_DisplayInfo.Opacity<0 || m_DisplayInfo.Opacity>100) m_DisplayInfo.Opacity = 100; byte c = binReader.ReadByte();
    nBytesRead += 1;
    if(c == 0x00) m_DisplayInfo.kind = false;
    else m_DisplayInfo.kind = true; nBytesRead += 1;
    m_DisplayInfo.padding = binReader.ReadByte();
    }
    break;
    case 1034:
    {
    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    int nCopyright = 0;
    if(SwapBytes(ShortValue,2)) nCopyright = BitConverter.ToInt16(ShortValue,0);
    if(nCopyright>0) m_bCopyright = true;
    else m_bCopyright = false;
    }
    break;
    case 1033:
      

  2.   

    case 1036:
    {
    m_bThumbnailFilled = true; IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ThumbNail.nFormat = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4; IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ThumbNail.nWidth = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4; IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ThumbNail.nHeight = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4; IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ThumbNail.nWidthBytes = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4; IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ThumbNail.nSize = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4; IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_ThumbNail.nCompressedSize = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4;

    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_ThumbNail.nBitPerPixel = BitConverter.ToInt16(ShortValue,0); ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_ThumbNail.nPlanes = BitConverter.ToInt16(ShortValue,0);

    int nTotalData = m_ImageResource.nSize - 28; // header byte [] buffer = new byte[nTotalData];
    byte c;
    if(m_ImageResource.nID == 1033)
    {
    // In BGR format
    for(int n=0; n<nTotalData; n=n+3)
    {
    c = binReader.ReadByte();
    nBytesRead += 1;
    buffer[n+2] = c;
    c = binReader.ReadByte();
    nBytesRead += 1;
    buffer[n+1] = c;
    c = binReader.ReadByte();
    nBytesRead += 1;
    buffer[n] = c;
    }
    }
    else if(m_ImageResource.nID == 1036)
    {
    // In RGB format
    for (int n=0; n<nTotalData; ++n)
    {
    c = binReader.ReadByte();
    nBytesRead += 1;
    buffer[n] = c;
    }
    }
    }
    break;
    case 1037:
    {
    IntValue = binReader.ReadBytes(4);
    if(SwapBytes(IntValue,4)) m_nGlobalAngle = BitConverter.ToInt32(IntValue,0);
    nBytesRead += 4;
    }
    break;
    case 1046:
    {
    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_nColourCount = BitConverter.ToInt16(ShortValue,0);
    }
    break;
    case 1047:
    {
    ShortValue = binReader.ReadBytes(2);
    nBytesRead += 2;
    if(SwapBytes(ShortValue,2)) m_nTransparentIndex = BitConverter.ToInt16(ShortValue,0);
    }
    break;
    default:
    {
    byte c;
    for(int n=0; n<m_ImageResource.nSize; ++n )
    {
    c = binReader.ReadByte();
    nBytesRead += 1;
    }
    }
    break;
    }
    }
    }
    }
    bSuccess = true;
    }
    catch(EndOfStreamException e)
    {
    bSuccess = false;
    MessageBox.Show("Exception occurs while reading image resources: {0}", e.GetType().Name);
    }


    return bSuccess;
    } protected bool ReadLayerAndMaskInfoSection(FileStream stream) // currently ignore it
    {
    bool bSuccess = false;

    BinaryReader binReader = new BinaryReader(stream);
    try
    {
    byte [] DataLength = new byte[4];
    int nTotalBytes =  0; DataLength = binReader.ReadBytes(4);
    if(SwapBytes(DataLength,4)) nTotalBytes = BitConverter.ToInt32(DataLength,0);

    if(stream.Position+nTotalBytes < stream.Length) stream.Position += nTotalBytes; // byte c = 0x00;
    // for(int i=0;i<nTotalBytes;i++)
    // {
    // if(binReader.PeekChar() == -1) break;
    // c = binReader.ReadByte();
    // } bSuccess = true;
    }
    catch(EndOfStreamException e)
    {
    bSuccess = false;
    MessageBox.Show("Exception occurs while reading layer and mask section: {0}", e.GetType().Name);
    }

    return bSuccess;
    }