View Javadoc

1   package com.tapina.robe.swi.os;
2   
3   import com.tapina.robe.runtime.ByteArrayUtils;
4   
5   import java.awt.*;
6   import java.awt.image.*;
7   
8   /***
9    * Created by IntelliJ IDEA.
10   * User: gareth
11   * Date: Sep 4, 2003
12   * Time: 6:41:10 PM
13   */
14  public final class Sprite {
15      final byte[] data;
16      final String name;
17      final int width;
18      final int height;
19      final int bpp;
20  
21      final BufferedImage image;
22  
23      public Sprite(byte[] data) {
24          this.data = data;
25  
26          name = ByteArrayUtils.getStringN(data, 4, 12);
27  
28          // Only handle-old-format sprites
29          final int spriteType = ByteArrayUtils.getInt(data, 40);
30          if ((spriteType & 0xf8000000) == 0) {
31              final int mode = (spriteType & 0x0000007f);
32              switch (mode) {
33                  case 0:
34                  case 4:
35                  case 18:
36                  case 25:
37                      bpp = 1;
38                      break;
39                  case 1:
40                  case 5:
41                  case 19:
42                  case 26:
43                      bpp = 2;
44                      break;
45                  case 12:
46                  case 20:
47                  case 27:
48                      bpp = 4;
49                      break;
50                  case 28:
51                      bpp = 8;
52                      break;
53                  default:
54                      bpp = 4;
55              }
56              final int firstBit = ByteArrayUtils.getInt(data, 24);
57              final int lastBit = ByteArrayUtils.getInt(data, 28);
58              final int scanLineStride = (ByteArrayUtils.getInt(data, 16) + 1) * 4;
59              width = (scanLineStride * 8 - (firstBit + (31 - lastBit))) / bpp;
60              height = ByteArrayUtils.getInt(data, 20) + 1;
61  
62              final SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, width, height,
63                                                               bpp, scanLineStride, firstBit);
64              final int spriteOffset = ByteArrayUtils.getInt(data, 32);
65              final int maskOffset = ByteArrayUtils.getInt(data, 36);
66              final DataBuffer dataBuffer = new DataBufferByte(data,
67                                                               scanLineStride * height,
68                                                               spriteOffset);
69              final WritableRaster raster = Raster.createWritableRaster(sm, dataBuffer, new Point());
70  
71              final int colours = 1<<bpp;
72              final int[] palette = new int[colours];
73              if (spriteOffset > 44 && maskOffset > 44) {
74                  // Has a palette
75                  for (int i = 0; i < colours; i++) {
76                      int acornPaletteEntry = ByteArrayUtils.getInt(data, 44 + i * 8);
77                      palette[i] = ACORN_COLOR_MODEL.getRGB(acornPaletteEntry);
78                  }
79              }
80              final ColorModel colorModel = new IndexColorModel(bpp, 1<<bpp, palette, 0, true, 0,
81                                                                DataBuffer.TYPE_BYTE);
82              BufferedImage indexedImage = new BufferedImage(colorModel, raster, false, null);
83              // Have to convert to non-custom image format otherwise it does not display correctly
84              image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
85              int[] rgbArray = new int[width * height];
86              indexedImage.getRGB(0, 0, width, height, rgbArray, 0, width);
87              image.setRGB(0, 0, width, height, rgbArray, 0, width);
88          } else {
89              throw new RuntimeException("Cannot handle new format sprites");
90          }
91      }
92  
93      public final String getName() {
94          return name;
95      }
96  
97      private final static DirectColorModel ACORN_COLOR_MODEL =
98              new DirectColorModel(32, 0xff00, 0xff0000, 0xff000000);
99  //    private final static ColorModel DEFAULT_COLOR_MODEL =
100 //            ColorModel.getRGBdefault();
101 
102     public final BufferedImage getImage() {
103         return image;
104     }
105 }