Esempio n. 1
0
        public void    Save(System.IO.Stream output, Surface surface, DdsSaveConfigToken ddsToken, ProgressEventHandler progressCallback)
        {
            // For non-compressed textures, we need pixel width.
            int pixelWidth = 0;

            // Identify if we're a compressed image
            bool isCompressed = ((ddsToken.m_fileFormat == DdsFileFormat.DDS_FORMAT_DXT1) ||
                                 (ddsToken.m_fileFormat == DdsFileFormat.DDS_FORMAT_DXT3) ||
                                 (ddsToken.m_fileFormat == DdsFileFormat.DDS_FORMAT_DXT5));

            // Compute mip map count..
            int mipCount  = 1;
            int mipWidth  = surface.Width;
            int mipHeight = surface.Height;

            if (ddsToken.m_generateMipMaps)
            {
                // This breaks!

                while ((mipWidth > 1) || (mipHeight > 1))
                {
                    mipCount++;
                    mipWidth  /= 2;
                    mipHeight /= 2;
                }
            }

            // Populate bulk of our DdsHeader
            m_header.m_size        = m_header.Size();
            m_header.m_headerFlags = ( uint )(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_TEXTURE);

            if (isCompressed)
            {
                m_header.m_headerFlags |= ( uint )(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_LINEARSIZE);
            }
            else
            {
                m_header.m_headerFlags |= ( uint )(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_PITCH);
            }

            if (mipCount > 1)
            {
                m_header.m_headerFlags |= ( uint )(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_MIPMAP);
            }

            m_header.m_height = ( uint )surface.Height;
            m_header.m_width  = ( uint )surface.Width;

            if (isCompressed)
            {
                // Compresssed textures have the linear flag set.So pitchOrLinearSize
                // needs to contain the entire size of the DXT block.
                int blockCount = ((surface.Width + 3) / 4) * ((surface.Height + 3) / 4);
                int blockSize  = (ddsToken.m_fileFormat == 0) ? 8 : 16;
                m_header.m_pitchOrLinearSize = ( uint )(blockCount * blockSize);
            }
            else
            {
                // Non-compressed textures have the pitch flag set. So pitchOrLinearSize
                // needs to contain the row pitch of the main image. DWORD aligned too.
                switch (ddsToken.m_fileFormat)
                {
                case    DdsFileFormat.DDS_FORMAT_A8R8G8B8:
                case    DdsFileFormat.DDS_FORMAT_X8R8G8B8:
                case    DdsFileFormat.DDS_FORMAT_A8B8G8R8:
                case    DdsFileFormat.DDS_FORMAT_X8B8G8R8:
                    pixelWidth = 4;                                     // 32bpp
                    break;

                case    DdsFileFormat.DDS_FORMAT_A1R5G5B5:
                case    DdsFileFormat.DDS_FORMAT_A4R4G4B4:
                case    DdsFileFormat.DDS_FORMAT_R5G6B5:
                    pixelWidth = 2;                                     // 16bpp
                    break;

                case    DdsFileFormat.DDS_FORMAT_R8G8B8:
                    pixelWidth = 3;                                     // 24bpp
                    break;
                }

                // Compute row pitch
                m_header.m_pitchOrLinearSize = ( uint )(( int )m_header.m_width * pixelWidth);

#if     APPLY_PITCH_ALIGNMENT
                // Align to DWORD, if we need to.. (see notes about pitch alignment all over this code)
                m_header.m_pitchOrLinearSize = ( uint )((( int )m_header.m_pitchOrLinearSize + 3) & (~3));
#endif  //APPLY_PITCH_ALIGNMENT
            }

            m_header.m_depth        = 0;
            m_header.m_mipMapCount  = (mipCount == 1) ? 0 : ( uint )mipCount;
            m_header.m_reserved1_0  = 0;
            m_header.m_reserved1_1  = 0;
            m_header.m_reserved1_2  = 0;
            m_header.m_reserved1_3  = 0;
            m_header.m_reserved1_4  = 0;
            m_header.m_reserved1_5  = 0;
            m_header.m_reserved1_6  = 0;
            m_header.m_reserved1_7  = 0;
            m_header.m_reserved1_8  = 0;
            m_header.m_reserved1_9  = 0;
            m_header.m_reserved1_10 = 0;

            // Populate our DdsPixelFormat object
            m_header.m_pixelFormat.Initialise(ddsToken.m_fileFormat);

            // Populate miscellanous header flags
            m_header.m_surfaceFlags = ( uint )DdsHeader.SurfaceFlags.DDS_SURFACE_FLAGS_TEXTURE;

            if (mipCount > 1)
            {
                m_header.m_surfaceFlags |= ( uint )DdsHeader.SurfaceFlags.DDS_SURFACE_FLAGS_MIPMAP;
            }

            m_header.m_cubemapFlags = 0;
            m_header.m_reserved2_0  = 0;
            m_header.m_reserved2_1  = 0;
            m_header.m_reserved2_2  = 0;

            // Write out our DDS tag
            Utility.WriteUInt32(output, 0x20534444);               // 'DDS '

            // Write out the header
            m_header.Write(output);

            int squishFlags = ddsToken.GetSquishFlags();

            // Our output data array will be sized as necessary
            byte[] outputData;

            // Reset our mip width & height variables...
            mipWidth  = surface.Width;
            mipHeight = surface.Height;

            // Figure out how much total work each mip map is
            Size[] writeSizes      = new Size[mipCount];
            int[]  mipPixels       = new int[mipCount];
            int[]  pixelsCompleted = new int[mipCount]; // # pixels completed once we have reached this mip
            long   totalPixels     = 0;
            for (int mipLoop = 0; mipLoop < mipCount; mipLoop++)
            {
                Size writeSize = new Size((mipWidth > 0) ? mipWidth : 1, (mipHeight > 0) ? mipHeight : 1);
                writeSizes[mipLoop] = writeSize;

                int thisMipPixels = writeSize.Width * writeSize.Height;
                mipPixels[mipLoop] = thisMipPixels;

                if (mipLoop == 0)
                {
                    pixelsCompleted[mipLoop] = 0;
                }
                else
                {
                    pixelsCompleted[mipLoop] = pixelsCompleted[mipLoop - 1] + mipPixels[mipLoop - 1];
                }

                totalPixels += thisMipPixels;
                mipWidth    /= 2;
                mipHeight   /= 2;
            }

            mipWidth  = surface.Width;
            mipHeight = surface.Height;

            for (int mipLoop = 0; mipLoop < mipCount; mipLoop++)
            {
                Size    writeSize    = writeSizes[mipLoop];
                Surface writeSurface = new Surface(writeSize);

                if (mipLoop == 0)
                {
                    // No point resampling the first level.. it's got exactly what we want.
                    writeSurface = surface;
                }
                else
                {
                    // I'd love to have a UI component to select what kind of resampling, but
                    // there's hardly any space for custom UI stuff in the Save Dialog. And I'm
                    // not having any scrollbars in there..!
                    // Also, note that each mip level is formed from the main level, to reduce
                    // compounded errors when generating mips.
                    writeSurface.SuperSamplingFitSurface(surface);
                }

                DdsSquish.ProgressFn progressFn =
                    delegate(int workDone, int workTotal)
                {
                    long   thisMipPixelsDone      = workDone * (long)mipWidth;
                    long   previousMipsPixelsDone = pixelsCompleted[mipLoop];
                    double progress = (double)((double)thisMipPixelsDone + (double)previousMipsPixelsDone) / (double)totalPixels;
                    progressCallback(this, new ProgressEventArgs(100.0 * progress));
                };

                if ((ddsToken.m_fileFormat >= DdsFileFormat.DDS_FORMAT_DXT1) && (ddsToken.m_fileFormat <= DdsFileFormat.DDS_FORMAT_DXT5))
                {
                    outputData = DdsSquish.CompressImage(writeSurface, squishFlags, (progressCallback == null) ? null : progressFn);
                }
                else
                {
                    int mipPitch = pixelWidth * writeSurface.Width;

                    // From the DDS documents I read, I'd expected the pitch of each mip level to be
                    // DWORD aligned. As it happens, that's not the case. Re-aligning the pitch of
                    // each level results in later mips getting sheared as the pitch is incorrect.
                    // So, the following line is intentionally optional. Maybe the documentation
                    // is referring to the pitch when accessing the mip directly.. who knows.
                    //
                    // Infact, all the talk of non-compressed textures having DWORD alignment of pitch
                    // seems to be bollocks.. If I apply alignment, then they fail to load in 3rd Party
                    // or Microsoft DDS viewing applications.
                    //

#if     APPLY_PITCH_ALIGNMENT
                    mipPitch = (mipPitch + 3) & (~3);
#endif // APPLY_PITCH_ALIGNMENT

                    outputData = new byte[mipPitch * writeSurface.Height];
                    outputData.Initialize();

                    for (int y = 0; y < writeSurface.Height; y++)
                    {
                        for (int x = 0; x < writeSurface.Width; x++)
                        {
                            // Get colour from surface
                            ColorBgra pixelColour = writeSurface.GetPoint(x, y);
                            uint      pixelData   = 0;

                            switch (ddsToken.m_fileFormat)
                            {
                            case    DdsFileFormat.DDS_FORMAT_A8R8G8B8:
                            {
                                pixelData = (( uint )pixelColour.A << 24) |
                                            (( uint )pixelColour.R << 16) |
                                            (( uint )pixelColour.G << 8) |
                                            (( uint )pixelColour.B << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_X8R8G8B8:
                            {
                                pixelData = (( uint )pixelColour.R << 16) |
                                            (( uint )pixelColour.G << 8) |
                                            (( uint )pixelColour.B << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_A8B8G8R8:
                            {
                                pixelData = (( uint )pixelColour.A << 24) |
                                            (( uint )pixelColour.B << 16) |
                                            (( uint )pixelColour.G << 8) |
                                            (( uint )pixelColour.R << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_X8B8G8R8:
                            {
                                pixelData = (( uint )pixelColour.B << 16) |
                                            (( uint )pixelColour.G << 8) |
                                            (( uint )pixelColour.R << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_A1R5G5B5:
                            {
                                pixelData = (( uint )((pixelColour.A != 0) ? 1 : 0) << 15) |
                                            (( uint )(pixelColour.R >> 3) << 10) |
                                            (( uint )(pixelColour.G >> 3) << 5) |
                                            (( uint )(pixelColour.B >> 3) << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_A4R4G4B4:
                            {
                                pixelData = (( uint )(pixelColour.A >> 4) << 12) |
                                            (( uint )(pixelColour.R >> 4) << 8) |
                                            (( uint )(pixelColour.G >> 4) << 4) |
                                            (( uint )(pixelColour.B >> 4) << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_R8G8B8:
                            {
                                pixelData = (( uint )pixelColour.R << 16) |
                                            (( uint )pixelColour.G << 8) |
                                            (( uint )pixelColour.B << 0);
                                break;
                            }

                            case    DdsFileFormat.DDS_FORMAT_R5G6B5:
                            {
                                pixelData = (( uint )(pixelColour.R >> 3) << 11) |
                                            (( uint )(pixelColour.G >> 2) << 5) |
                                            (( uint )(pixelColour.B >> 3) << 0);
                                break;
                            }
                            }

                            // pixelData contains our target data.. so now set the pixel bytes
                            int pixelOffset = (y * mipPitch) + (x * pixelWidth);
                            for (int loop = 0; loop < pixelWidth; loop++)
                            {
                                outputData[pixelOffset + loop] = ( byte )((pixelData >> (8 * loop)) & 0xff);
                            }
                        }

                        if (progressCallback != null)
                        {
                            long   thisMipPixelsDone      = (y + 1) * (long)mipWidth;
                            long   previousMipsPixelsDone = pixelsCompleted[mipLoop];
                            double progress = (double)((double)thisMipPixelsDone + (double)previousMipsPixelsDone) / (double)totalPixels;
                            progressCallback(this, new ProgressEventArgs(100.0 * progress));
                        }
                    }
                }

                // Write the data for this mip level out..
                output.Write(outputData, 0, outputData.GetLength(0));

                mipWidth  = mipWidth / 2;
                mipHeight = mipHeight / 2;
            }
        }
Esempio n. 2
0
        public void    Load(System.IO.Stream input)
        {
            // Read the DDS tag. If it's not right, then bail..
            uint ddsTag = ( uint )Utility.ReadUInt32(input);

            if (ddsTag != 0x20534444)
            {
                throw new FormatException("File does not appear to be a DDS image");
            }

            // Read everything in.. for now assume it worked like a charm..
            m_header.Read(input);

            if ((m_header.m_pixelFormat.m_flags & ( int )DdsPixelFormat.PixelFormatFlags.DDS_FOURCC) != 0)
            {
                int squishFlags = 0;

                switch (m_header.m_pixelFormat.m_fourCC)
                {
                case    0x31545844:
                    squishFlags = ( int )DdsSquish.SquishFlags.kDxt1;
                    break;

                case    0x33545844:
                    squishFlags = ( int )DdsSquish.SquishFlags.kDxt3;
                    break;

                case    0x35545844:
                    squishFlags = ( int )DdsSquish.SquishFlags.kDxt5;
                    break;

                default:
                    throw new FormatException("File is not a supported DDS format");
                }

                // Compute size of compressed block area
                int blockCount = ((GetWidth() + 3) / 4) * ((GetHeight() + 3) / 4);
                int blockSize  = ((squishFlags & ( int )DdsSquish.SquishFlags.kDxt1) != 0) ? 8 : 16;

                // Allocate room for compressed blocks, and read data into it.
                byte[] compressedBlocks = new byte[blockCount * blockSize];
                input.Read(compressedBlocks, 0, compressedBlocks.GetLength(0));

                // Now decompress..
                m_pixelData = DdsSquish.DecompressImage(compressedBlocks, GetWidth(), GetHeight(), squishFlags);
            }
            else
            {
                // We can only deal with the non-DXT formats we know about..  this is a bit of a mess..
                // Sorry..
                DdsFileFormat fileFormat = DdsFileFormat.DDS_FORMAT_INVALID;

                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGBA) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 32) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x00ff0000) && (m_header.m_pixelFormat.m_gBitMask == 0x0000ff00) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x000000ff) && (m_header.m_pixelFormat.m_aBitMask == 0xff000000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_A8R8G8B8;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGB) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 32) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x00ff0000) && (m_header.m_pixelFormat.m_gBitMask == 0x0000ff00) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x000000ff) && (m_header.m_pixelFormat.m_aBitMask == 0x00000000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_X8R8G8B8;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGBA) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 32) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x000000ff) && (m_header.m_pixelFormat.m_gBitMask == 0x0000ff00) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x00ff0000) && (m_header.m_pixelFormat.m_aBitMask == 0xff000000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_A8B8G8R8;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGB) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 32) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x000000ff) && (m_header.m_pixelFormat.m_gBitMask == 0x0000ff00) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x00ff0000) && (m_header.m_pixelFormat.m_aBitMask == 0x00000000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_X8B8G8R8;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGBA) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 16) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x00007c00) && (m_header.m_pixelFormat.m_gBitMask == 0x000003e0) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x0000001f) && (m_header.m_pixelFormat.m_aBitMask == 0x00008000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_A1R5G5B5;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGBA) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 16) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x00000f00) && (m_header.m_pixelFormat.m_gBitMask == 0x000000f0) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x0000000f) && (m_header.m_pixelFormat.m_aBitMask == 0x0000f000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_A4R4G4B4;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGB) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 24) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x00ff0000) && (m_header.m_pixelFormat.m_gBitMask == 0x0000ff00) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x000000ff) && (m_header.m_pixelFormat.m_aBitMask == 0x00000000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_R8G8B8;
                }
                else
                if ((m_header.m_pixelFormat.m_flags == ( int )DdsPixelFormat.PixelFormatFlags.DDS_RGB) &&
                    (m_header.m_pixelFormat.m_rgbBitCount == 16) &&
                    (m_header.m_pixelFormat.m_rBitMask == 0x0000f800) && (m_header.m_pixelFormat.m_gBitMask == 0x000007e0) &&
                    (m_header.m_pixelFormat.m_bBitMask == 0x0000001f) && (m_header.m_pixelFormat.m_aBitMask == 0x00000000))
                {
                    fileFormat = DdsFileFormat.DDS_FORMAT_R5G6B5;
                }

                // If fileFormat is still invalid, then it's an unsupported format.
                if (fileFormat == DdsFileFormat.DDS_FORMAT_INVALID)
                {
                    throw new FormatException("File is not a supported DDS format");
                }

                // Size of a source pixel, in bytes
                int srcPixelSize = (( int )m_header.m_pixelFormat.m_rgbBitCount / 8);

                // We need the pitch for a row, so we can allocate enough memory for the load.
                int rowPitch = 0;

                if ((m_header.m_headerFlags & ( int )DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_PITCH) != 0)
                {
                    // Pitch specified.. so we can use directly
                    rowPitch = ( int )m_header.m_pitchOrLinearSize;
                }
                else
                if ((m_header.m_headerFlags & ( int )DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_LINEARSIZE) != 0)
                {
                    // Linear size specified.. compute row pitch. Of course, this should never happen
                    // as linear size is *supposed* to be for compressed textures. But Microsoft don't
                    // always play by the rules when it comes to DDS output.
                    rowPitch = ( int )m_header.m_pitchOrLinearSize / ( int )m_header.m_height;
                }
                else
                {
                    // Another case of Microsoft not obeying their standard is the 'Convert to..' shell extension
                    // that ships in the DirectX SDK. Seems to always leave flags empty..so no indication of pitch
                    // or linear size. And - to cap it all off - they leave pitchOrLinearSize as *zero*. Zero??? If
                    // we get this bizarre set of inputs, we just go 'screw it' and compute row pitch ourselves,
                    // making sure we DWORD align it (if that code path is enabled).
                    rowPitch = (( int )m_header.m_width * srcPixelSize);

#if     APPLY_PITCH_ALIGNMENT
                    rowPitch = ((( int )rowPitch + 3) & (~3));
#endif  // APPLY_PITCH_ALIGNMENT
                }

//				System.Diagnostics.Debug.WriteLine( "Image width : " + m_header.m_width + ", rowPitch = " + rowPitch );

                // Ok.. now, we need to allocate room for the bytes to read in from.. it's rowPitch bytes * height
                byte[] readPixelData = new byte[rowPitch * m_header.m_height];
                input.Read(readPixelData, 0, readPixelData.GetLength(0));

                // We now need space for the real pixel data.. that's width * height * 4..
                m_pixelData = new byte[m_header.m_width * m_header.m_height * 4];

                // And now we have the arduous task of filling that up with stuff..
                for (int destY = 0; destY < ( int )m_header.m_height; destY++)
                {
                    for (int destX = 0; destX < ( int )m_header.m_width; destX++)
                    {
                        // Compute source pixel offset
                        int srcPixelOffset = (destY * rowPitch) + (destX * srcPixelSize);

                        // Read our pixel
                        uint pixelColour = 0;
                        uint pixelRed    = 0;
                        uint pixelGreen  = 0;
                        uint pixelBlue   = 0;
                        uint pixelAlpha  = 0;

                        // Build our pixel colour as a DWORD
                        for (int loop = 0; loop < srcPixelSize; loop++)
                        {
                            pixelColour |= ( uint )(readPixelData[srcPixelOffset + loop] << (8 * loop));
                        }

                        if (fileFormat == DdsFileFormat.DDS_FORMAT_A8R8G8B8)
                        {
                            pixelAlpha = (pixelColour >> 24) & 0xff;
                            pixelRed   = (pixelColour >> 16) & 0xff;
                            pixelGreen = (pixelColour >> 8) & 0xff;
                            pixelBlue  = (pixelColour >> 0) & 0xff;
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_X8R8G8B8)
                        {
                            pixelAlpha = 0xff;
                            pixelRed   = (pixelColour >> 16) & 0xff;
                            pixelGreen = (pixelColour >> 8) & 0xff;
                            pixelBlue  = (pixelColour >> 0) & 0xff;
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_A8B8G8R8)
                        {
                            pixelAlpha = (pixelColour >> 24) & 0xff;
                            pixelRed   = (pixelColour >> 0) & 0xff;
                            pixelGreen = (pixelColour >> 8) & 0xff;
                            pixelBlue  = (pixelColour >> 16) & 0xff;
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_X8B8G8R8)
                        {
                            pixelAlpha = 0xff;
                            pixelRed   = (pixelColour >> 0) & 0xff;
                            pixelGreen = (pixelColour >> 8) & 0xff;
                            pixelBlue  = (pixelColour >> 16) & 0xff;
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_A1R5G5B5)
                        {
                            pixelAlpha = (pixelColour >> 15) * 0xff;
                            pixelRed   = (pixelColour >> 10) & 0x1f;
                            pixelGreen = (pixelColour >> 5) & 0x1f;
                            pixelBlue  = (pixelColour >> 0) & 0x1f;

                            pixelRed   = (pixelRed << 3) | (pixelRed >> 2);
                            pixelGreen = (pixelGreen << 3) | (pixelGreen >> 2);
                            pixelBlue  = (pixelBlue << 3) | (pixelBlue >> 2);
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_A4R4G4B4)
                        {
                            pixelAlpha = (pixelColour >> 12) & 0xff;
                            pixelRed   = (pixelColour >> 8) & 0x0f;
                            pixelGreen = (pixelColour >> 4) & 0x0f;
                            pixelBlue  = (pixelColour >> 0) & 0x0f;

                            pixelAlpha = (pixelAlpha << 4) | (pixelAlpha >> 0);
                            pixelRed   = (pixelRed << 4) | (pixelRed >> 0);
                            pixelGreen = (pixelGreen << 4) | (pixelGreen >> 0);
                            pixelBlue  = (pixelBlue << 4) | (pixelBlue >> 0);
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_R8G8B8)
                        {
                            pixelAlpha = 0xff;
                            pixelRed   = (pixelColour >> 16) & 0xff;
                            pixelGreen = (pixelColour >> 8) & 0xff;
                            pixelBlue  = (pixelColour >> 0) & 0xff;
                        }
                        else
                        if (fileFormat == DdsFileFormat.DDS_FORMAT_R5G6B5)
                        {
                            pixelAlpha = 0xff;
                            pixelRed   = (pixelColour >> 11) & 0x1f;
                            pixelGreen = (pixelColour >> 5) & 0x3f;
                            pixelBlue  = (pixelColour >> 0) & 0x1f;

                            pixelRed   = (pixelRed << 3) | (pixelRed >> 2);
                            pixelGreen = (pixelGreen << 2) | (pixelGreen >> 4);
                            pixelBlue  = (pixelBlue << 3) | (pixelBlue >> 2);
                        }

                        // Write the colours away..
                        int destPixelOffset = (destY * ( int )m_header.m_width * 4) + (destX * 4);
                        m_pixelData[destPixelOffset + 0] = ( byte )pixelRed;
                        m_pixelData[destPixelOffset + 1] = ( byte )pixelGreen;
                        m_pixelData[destPixelOffset + 2] = ( byte )pixelBlue;
                        m_pixelData[destPixelOffset + 3] = ( byte )pixelAlpha;
                    }
                }
            }
        }
Esempio n. 3
0
 public FileType[] GetFileTypeInstances()
 {
     DdsSquish.Initialize();
     return((FileType[])fileTypes.Clone());
 }