Esempio n. 1
0
        /*static IEnumerable<Point> GetPointSequence(ImageSettings settings)
         * {
         *  switch (settings.Format)
         *  {
         *      case Format.ATI1A:
         *      case Format.ATI1L:
         *      case Format.ATI2:
         *      case Format.ETC1:
         *      case Format.ETC1A4:
         *      case Format.DXT1:
         *      case Format.DXT3:
         *      case Format.DXT5:
         *          settings.TileSize = settings.TileSize + 3 & ~0x3;
         *          break;
         *  }
         *
         *  int strideWidth = (settings.Width + 7) & ~7;
         *  int strideHeight = (settings.Height + 7) & ~7;
         *  if (settings.PadToPowerOf2)
         *  {
         *      strideWidth = 2 << (int)Math.Log(strideWidth - 1, 2);
         *      strideHeight = 2 << (int)Math.Log(strideHeight - 1, 2);
         *  }
         *
         *  //stride TileSize
         *  var tileSize = 0;
         *  if (settings.ZOrder)
         *      tileSize = 2 << (int)(Math.Log(((settings.TileSize + 7) & ~7) - 1, 2));
         *  else
         *      tileSize = settings.TileSize;
         *  int powTileSize = (int)Math.Pow(tileSize, 2);
         *
         *  int stride = strideWidth;
         *  switch (settings.Orientation)
         *  {
         *      case Orientation.Rotate90:
         *      case Orientation.Transpose:
         *          stride = strideHeight;
         *          break;
         *  }
         *
         *  for (int i = 0; i < strideWidth * strideHeight; i++)
         *  {
         *      //in == order inside a tile
         *      //out == order of tiles themselves
         *      int x_out = 0, y_out = 0, x_in = 0, y_in = 0;
         *      if (settings.ZOrder)
         *      {
         *          x_out = (i / powTileSize % (stride / tileSize)) * tileSize;
         *          y_out = (i / powTileSize / (stride / tileSize)) * tileSize;
         *          x_in = ZOrderX(tileSize, i);
         *          y_in = ZOrderY(tileSize, i);
         *      }
         *      else
         *      {
         *          x_out = (i / powTileSize % (stride / tileSize)) * tileSize;
         *          y_out = (i / powTileSize / (stride / tileSize)) * tileSize;
         *
         *          switch (settings.Format)
         *          {
         *              case Format.ATI1A:
         *              case Format.ATI1L:
         *              case Format.ATI2:
         *              case Format.ETC1:
         *              case Format.ETC1A4:
         *              case Format.DXT1:
         *              case Format.DXT3:
         *              case Format.DXT5:
         *                  x_in = (i % 4 + i % powTileSize / 16 * 4) % tileSize;
         *                  y_in = (i % 16 / 4 + i / (tileSize * 4) * 4) % tileSize;
         *                  break;
         *              default:
         *                  x_in = i % powTileSize % tileSize;
         *                  y_in = i % powTileSize / tileSize;
         *                  break;
         *          }
         *      }
         *
         *      switch (settings.Orientation)
         *      {
         *          case Orientation.Default:
         *              yield return new Point(x_out + x_in, y_out + y_in);
         *              break;
         *          case Orientation.HorizontalFlip:
         *              yield return new Point(stride - 1 - (x_out + x_in), y_out + y_in);
         *              break;
         *          case Orientation.Rotate90:
         *              yield return new Point(y_out + y_in, stride - 1 - (x_out + x_in));
         *              break;
         *          case Orientation.Transpose:
         *              yield return new Point(y_out + y_in, x_out + x_in);
         *              break;
         *          case Orientation.TransposeTile:
         *              yield return new Point(x_out + y_in, y_out + x_in);
         *              break;
         *          default:
         *              throw new NotSupportedException($"Unknown orientation format {settings.Orientation}");
         *      }
         *  }
         * }
         * static int ZOrderX(int tileSize, int count)
         * {
         *  var div = tileSize / 2;
         *  var x_in = count / div & div;
         *
         *  while (div > 1)
         *  {
         *      div /= 2;
         *      x_in |= count / div & div;
         *  }
         *
         *  return x_in;
         * }
         * static int ZOrderY(int tileSize, int count)
         * {
         *  var div = tileSize;
         *  var div2 = tileSize / 2;
         *  var y_in = count / div & div2;
         *
         *  while (div2 > 1)
         *  {
         *      div /= 2;
         *      div2 /= 2;
         *      y_in |= count / div & div2;
         *  }
         *
         *  return y_in;
         * }*/

        /// <summary>
        /// Loads the binary data with given settings as an image
        /// </summary>
        /// <param name="tex">
        /// Bytearray containing the binary image data
        /// </param>
        /// <param name="settings">
        /// The settings determining the final image output
        /// </param>
        public static Bitmap Load(byte[] tex, ImageSettings settings)
        {
            int width = settings.Width, height = settings.Height;

            var points = GetPointSequence(settings);

            var bmp  = new Bitmap(width, height);
            var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                var ptr = (int *)data.Scan0;
                foreach (var pair in points.Zip(settings.Format.Load(tex), Tuple.Create))
                {
                    int x = pair.Item1.X, y = pair.Item1.Y;
                    if (0 <= x && x < width && 0 <= y && y < height)
                    {
                        var color = pair.Item2;
                        if (settings.PixelShader != null)
                        {
                            color = settings.PixelShader(color);
                        }
                        ptr[data.Stride * y / 4 + x] = color.ToArgb();
                    }
                }
            }
            bmp.UnlockBits(data);

            return(bmp);
        }
Esempio n. 2
0
        /// <summary>
        /// Gives back a sequence of points, modified by Swizzles if applied
        /// </summary>
        static IEnumerable <Point> GetPointSequence(ImageSettings settings)
        {
            int strideWidth  = (settings.Swizzle != null) ? settings.Swizzle.Width : settings.Width;
            int strideHeight = (settings.Swizzle != null) ? settings.Swizzle.Height : settings.Height;

            for (int i = 0; i < strideWidth * strideHeight; i++)
            {
                var point = new Point(i % strideWidth, i / strideWidth);
                if (settings.Swizzle != null)
                {
                    point = settings.Swizzle.Get(point);
                }

                yield return(point);
            }
        }
Esempio n. 3
0
        static IEnumerable <Point> GetInnerTile(ImageSettings settings)
        {
            int tileSize    = settings.TileSize;
            int powTileSize = (int)Math.Pow(tileSize, 2);

            for (int i = 0; i < powTileSize; i++)
            {
                if (settings.InnerSwizzle == null)
                {
                    yield return(new Point(i % powTileSize % tileSize, i % powTileSize / tileSize));
                }
                else
                {
                    yield return(settings.InnerSwizzle.InnerLoad(i, tileSize));
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Converts a given Bitmap, modified by given settings, in binary data
        /// </summary>
        /// <param name="bmp">The bitmap, which will be converted</param>
        /// <param name="settings">Settings like Format, Dimensions and Swizzles</param>
        /// <returns>byte[]</returns>
        public static byte[] Save(Bitmap bmp, ImageSettings settings)
        {
            var points = GetPointSequence(settings);
            var colors = new List <Color>();

            foreach (var point in points)
            {
                int x = Clamp(point.X, 0, bmp.Width);
                int y = Clamp(point.Y, 0, bmp.Height);

                var color = bmp.GetPixel(x, y);
                if (settings.PixelShader != null)
                {
                    color = settings.PixelShader(color);
                }

                colors.Add(color);
            }

            return(settings.Format.Save(colors));
        }
Esempio n. 5
0
        /// <summary>
        /// Gives back a sequence of points, modified by Swizzles if applied
        /// </summary>
        static IEnumerable <Point> GetPointSequence(ImageSettings settings)
        {
            int tileSize    = settings.TileSize;
            int powTileSize = (int)Math.Pow(tileSize, 2);

            int strideWidth  = (settings.Width + (tileSize - 1)) & ~(tileSize - 1);
            int strideHeight = (settings.Height + (tileSize - 1)) & ~(tileSize - 1);

            if (settings.PadToPowerOf2)
            {
                strideWidth  = 2 << (int)Math.Log(strideWidth - 1, 2);
                strideHeight = 2 << (int)Math.Log(strideHeight - 1, 2);
            }

            int stride = strideWidth;

            for (int i = 0; i < strideWidth * strideHeight; i += powTileSize)
            {
                var innerTile = GetInnerTile(settings);
                foreach (var point in innerTile)
                {
                    if (settings.OuterSwizzle == null)
                    {
                        var point2 = new Point(
                            ((i / powTileSize % (stride / tileSize)) * tileSize) + point.X,
                            ((i / powTileSize / (stride / tileSize)) * tileSize) + point.Y);
                        yield return(point2);
                    }
                    else
                    {
                        var point2 = settings.OuterSwizzle.OuterLoad(i, tileSize, strideWidth);
                        point2.X += point.X;
                        point2.Y += point.Y;
                        yield return(point2);
                    }
                }
            }
        }