public static int GetPixelFormatDepth(GSPixelFormat fmt)
        {
            switch (fmt)
            {
            case GSPixelFormat.PSMTC32:
            case GSPixelFormat.PSMZ32:
            case GSPixelFormat.PSMZ24:
                return(32);

            case GSPixelFormat.PSMTC24:
                return(24);

            case GSPixelFormat.PSMTC16:
            case GSPixelFormat.PSMTC16S:
            case GSPixelFormat.PSMZ16:
            case GSPixelFormat.PSMZ16S:
                return(16);

            case GSPixelFormat.PSMT8:
            case GSPixelFormat.PSMT8H:
                return(8);

            case GSPixelFormat.PSMT4:
            case GSPixelFormat.PSMT4HL:
            case GSPixelFormat.PSMT4HH:
                return(4);

            default:
                throw new ArgumentException(EXCEPTION_INVALID_PXFORMAT, nameof(fmt));
            }
        }
        public static int GetTexelDataSize(GSPixelFormat fmt, int width, int height)
        {
            switch (fmt)
            {
            case GSPixelFormat.PSMTC32:
            case GSPixelFormat.PSMTC24:
            case GSPixelFormat.PSMZ32:
            case GSPixelFormat.PSMZ24:
                return((width * height) * 4);

            case GSPixelFormat.PSMTC16:
            case GSPixelFormat.PSMTC16S:
            case GSPixelFormat.PSMZ16:
            case GSPixelFormat.PSMZ16S:
                return((width * height) * 2);

            case GSPixelFormat.PSMT8:
            case GSPixelFormat.PSMT8H:
                return((width * height) * 1);

            case GSPixelFormat.PSMT4:
            case GSPixelFormat.PSMT4HL:
            case GSPixelFormat.PSMT4HH:
                return((width * height) / 2);      // 4 bit index only takes up half a texel

            default:
                throw new ArgumentException(EXCEPTION_INVALID_PXFORMAT, nameof(fmt));
            }
        }
 public static void WritePixelData <T>(GSPixelFormat fmt, BinaryWriter writer, int width, int height, T[] array)
 {
     if (IsIndexedPixelFormat(fmt))
     {
         var writePixelIndices = GetWritePixelIndicesDelegate(fmt);
         writePixelIndices(writer, width, height, array as byte[]);
     }
     else
     {
         var writePixels = GetWritePixelColorDelegate(fmt);
         writePixels(writer, width, height, array as Color[]);
     }
 }
        // generic read/write methods

        public static T[] ReadPixelData <T>(GSPixelFormat fmt, BinaryReader reader, int width, int height)
        {
            if (IsIndexedPixelFormat(fmt))
            {
                var readPixelIndices = GetReadPixelIndicesDelegate(fmt);
                return(readPixelIndices(reader, width, height) as T[]);
            }
            else
            {
                var readPixels = GetReadPixelColorDelegate(fmt);
                return(readPixels(reader, width, height) as T[]);
            }
        }
        // alpha scalers



        // helper methods to get info about the pixel format

        public static int GetPaletteDimension(GSPixelFormat imageFmt)
        {
            int paletteWH = 16;

            if (imageFmt == GSPixelFormat.PSMT4 ||
                imageFmt == GSPixelFormat.PSMT4HH ||
                imageFmt == GSPixelFormat.PSMT4HL)
            {
                paletteWH = 4;
            }

            return(paletteWH);
        }
 public static bool IsIndexedPixelFormat(GSPixelFormat fmt)
 {
     switch (fmt)
     {
     case GSPixelFormat.PSMT8:
     case GSPixelFormat.PSMT4:
     case GSPixelFormat.PSMT8H:
     case GSPixelFormat.PSMT4HL:
     case GSPixelFormat.PSMT4HH:
         return(true);
     }
     return(false);
 }
        public static int GetIndexedColorCount(GSPixelFormat fmt)
        {
            switch (fmt)
            {
            case GSPixelFormat.PSMT8:
            case GSPixelFormat.PSMT8H:
                return(256);

            case GSPixelFormat.PSMT4:
            case GSPixelFormat.PSMT4HL:
            case GSPixelFormat.PSMT4HH:
                return(16);

            default:
                throw new ArgumentException(EXCEPTION_INVALID_PXFORMAT, nameof(fmt));
            }
        }
        public static WritePixelIndicesDelegate GetWritePixelIndicesDelegate(GSPixelFormat fmt)
        {
            switch (fmt)
            {
            case GSPixelFormat.PSMT8:
            case GSPixelFormat.PSMT8H:
                return(WritePSMT8);

            case GSPixelFormat.PSMT4:
            case GSPixelFormat.PSMT4HL:
            case GSPixelFormat.PSMT4HH:
                return(WritePSMT4);

            default:
                throw new ArgumentException(EXCEPTION_INVALID_PXFORMAT, nameof(fmt));
            }
        }
        public static WritePixelColorDelegate GetWritePixelColorDelegate(GSPixelFormat fmt)
        {
            switch (fmt)
            {
            case GSPixelFormat.PSMTC32:
            case GSPixelFormat.PSMZ32:
                return(WritePSMCT32);

            case GSPixelFormat.PSMZ24:
            case GSPixelFormat.PSMTC24:
                return(WritePSMCT24);

            case GSPixelFormat.PSMTC16:
            case GSPixelFormat.PSMZ16:
                return(WritePSMCT16);

            case GSPixelFormat.PSMZ16S:
            case GSPixelFormat.PSMTC16S:
                return(WritePSMCT16S);

            default:
                throw new ArgumentException(EXCEPTION_INVALID_PXFORMAT, nameof(fmt));
            }
        }