code: package org.sunflow.image.writers;
  
  import java.io.BufferedOutputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  
  import org.sunflow.image.BitmapWriter;
  import org.sunflow.image.Color;
  import org.sunflow.image.ColorEncoder;
  
  public class TGABitmapWriter implements BitmapWriter {
      private String filename;
      private int width, height;
      private byte[] data;
  
      public void configure(String option, String value) {
      }
  
      public void openFile(String filename) throws IOException {
          this.filename = filename;
      }
  
      public void writeHeader(int width, int height, int tileSize) throws IOException, UnsupportedOperationException {
          this.width = width;
          this.height = height;
          data = new byte[width * height * 4]; // RGBA8
      }
  
      public void writeTile(int x, int y, int w, int h, Color[] color, float[] alpha) throws IOException {
          color = ColorEncoder.unlinearize(color); // gamma correction
          byte[] tileData = ColorEncoder.quantizeRGBA8(color, alpha);
          for (int j = 0, index = 0; j < h; j++) {
              int imageIndex = 4 * (x + (height - 1 - (y + j)) * width);
              for (int i = 0; i < w; i++, index += 4, imageIndex += 4) {
                  // swap bytes around so buffer is in native BGRA order
                  data[imageIndex + 0] = tileData[index + 2];
                  data[imageIndex + 1] = tileData[index + 1];
                  data[imageIndex + 2] = tileData[index + 0];
                  data[imageIndex + 3] = tileData[index + 3];
              }
          }
      }
  
      public void closeFile() throws IOException {
          // actually write the file from here
          OutputStream f = new BufferedOutputStream(new FileOutputStream(filename));
          // no id, no colormap, uncompressed 32bpp RGBA
          byte[] tgaHeader = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
          f.write(tgaHeader);
          // then the size info
          f.write(width & 0xFF);
          f.write((width >> 8) & 0xFF);
          f.write(height & 0xFF);
          f.write((height >> 8) & 0xFF);
          // bitsperpixel and filler
          f.write(32);
          f.write(0);
          f.write(data); // write image data bytes (already in BGRA order)
          f.close();
      }
  }