summaryrefslogtreecommitdiff
path: root/libjava/java/awt/image/PackedColorModel.java
blob: a72ae2d0efac31e405da70ffb4063206157161f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* Copyright © 2000  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.awt.image;

import java.awt.Point;
import java.awt.color.ColorSpace;
import gnu.gcj.awt.BitMaskExtent;

/**
 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
 */
public abstract class PackedColorModel extends ColorModel
{
  private int masks[];
  
  /* Package accessibility, the DirectColorModel needs this array */
  int shifts[];

  public PackedColorModel(ColorSpace cspace, int pixelBits,
			  int[] colorMaskArray, int alphaMask,
			  boolean isAlphaPremultiplied,
			  int transparency,
			  int transferType)
  {
    super(pixelBits, calcBitsPerComponent(colorMaskArray, alphaMask),
	  cspace, (alphaMask != 0), isAlphaPremultiplied, transparency,
	  transferType);
    initMasks(colorMaskArray, alphaMask);
    if ((pixelBits<1) || (pixelBits>32)) {
      throw new IllegalArgumentException("pixels per bits must be " +
					 "in the range [1, 32]");
    }
  }
    
  private static int[] calcBitsPerComponent(int[] colorMaskArray,
					    int alphaMask)
  {
    int numComponents = colorMaskArray.length;
    if (alphaMask != 0) numComponents++;
    
    int[] bitsPerComponent = new int[numComponents];
    
    BitMaskExtent extent = new BitMaskExtent();
    for (int b=0; b<colorMaskArray.length; b++)
      {
	extent.setMask(colorMaskArray[b]);
	bitsPerComponent[b] = extent.bitWidth;
      }
    if (alphaMask != 0)
      {
	extent.setMask(alphaMask);
	bitsPerComponent[numComponents-1] = extent.bitWidth;
      }
    return bitsPerComponent;
  }

  /** Initializes the masks.
   *
   * @return an array containing the number of bits per color
   * component.
   */
  private void initMasks(int[] colorMaskArray, int alphaMask)
  {
    int numComponents = colorMaskArray.length;
    if (alphaMask == 0)
      {
	masks = colorMaskArray;
      }
    else
      {
	masks = new int[numComponents+1];
	System.arraycopy(colorMaskArray, 0,
			 masks, 0,
			 numComponents);
	masks[numComponents++] = alphaMask;
      }
	
    shifts = new int[numComponents];
	
    // Bit field handling have been moved to a utility class
    BitMaskExtent extent = new BitMaskExtent();
    for (int b=0; b<numComponents; b++)
      {
	extent.setMask(masks[b]);
	shifts[b] = extent.leastSignificantBit;
      }
  }
    
  public PackedColorModel(ColorSpace cspace, int pixelBits,
			  int rmask, int gmask, int bmask,
			  int amask, boolean isAlphaPremultiplied,
			  int transparency,
			  int transferType)
  {
    this(cspace, pixelBits, makeColorMaskArray(rmask, gmask, bmask),
	 amask, isAlphaPremultiplied, transparency, transferType);
  }
    
  /* TODO: If there is a alpha mask, it is inefficient to create a
     color mask array that will be discarded when the alpha mask is
     appended. We should probably create a private constructor that
     takes a complete array of masks (color+alpha) as an
     argument. */

  private static int[] makeColorMaskArray(int rmask, int gmask, int bmask)
  {
    int[] colorMaskArray = { rmask, gmask, bmask };
    return colorMaskArray;
  }   

  public final int getMask(int index)
  {
    return masks[index];
  }
  
  public final int[] getMasks()
  {
    return masks;
  }

  public SampleModel createCompatibleSampleModel(int w, int h)
  {
    return new SinglePixelPackedSampleModel(transferType, w, h, masks);
  }
    
  public boolean isCompatibleSampleModel(SampleModel sm)
  {
    if (!super.isCompatibleSampleModel(sm)) return false;
    if (!(sm instanceof SinglePixelPackedSampleModel)) return false;
    
    SinglePixelPackedSampleModel sppsm =
      (SinglePixelPackedSampleModel) sm;
    return java.util.Arrays.equals(sppsm.getBitMasks(), masks);
  }

  public WritableRaster getAlphaRaster(WritableRaster raster) {
    if (!hasAlpha()) return null;
	
    SampleModel sm = raster.getSampleModel();
    int[] alphaBand = { sm.getNumBands() - 1 };
    SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
    DataBuffer buffer = raster.getDataBuffer();
    Point origin = new Point(0, 0);
    return Raster.createWritableRaster(alphaModel, buffer, origin);
  }
    
  public boolean equals(Object obj)
  {
    if (!super.equals(obj)) return false;
    if (!(obj instanceof PackedColorModel)) return false;
    
    PackedColorModel other = (PackedColorModel) obj;
    
    return java.util.Arrays.equals(masks, other.masks);
  }
}