001 /* 002 * PaletteSerialization 003 * 004 * Copyright (c) 2001, 2002, 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.color.io; 009 010 import java.io.File; 011 import java.io.FileOutputStream; 012 import java.io.IOException; 013 import java.util.Vector; 014 import net.sourceforge.jiu.codecs.ImageLoader; 015 import net.sourceforge.jiu.codecs.PNMCodec; 016 import net.sourceforge.jiu.data.MemoryRGB24Image; 017 import net.sourceforge.jiu.data.Palette; 018 import net.sourceforge.jiu.data.PixelImage; 019 import net.sourceforge.jiu.data.RGB24Image; 020 import net.sourceforge.jiu.data.RGBIndex; 021 import net.sourceforge.jiu.ops.OperationFailedException; 022 023 /** 024 * This class loads and saves palettes. 025 * Loading is done using the {@link ImageLoader} class - an image 026 * is loaded which is supposed to have no more than 256 pixels, the palette entries. 027 * When saving, the {@link PNMCodec} is used to store palettes as .ppm files. 028 * 029 * @author Marco Schmidt 030 * @since 0.5.0 031 */ 032 public class PaletteSerialization implements RGBIndex 033 { 034 private PaletteSerialization() 035 { 036 } 037 038 /** 039 * Create a palette from the pixels of the argument image. 040 */ 041 public static Palette convertImageToPalette(RGB24Image image) 042 { 043 if (image == null) 044 { 045 return null; 046 } 047 int numPixels = image.getWidth() * image.getHeight(); 048 if (numPixels > 256) 049 { 050 // too many pixels 051 return null; 052 } 053 Palette result = new Palette(numPixels, 255); 054 int index = 0; 055 for (int y = 0; y < image.getHeight(); y++) 056 { 057 for (int x = 0; x < image.getWidth(); x++) 058 { 059 result.put(index++, image.getSample(INDEX_RED, x, y), 060 image.getSample(INDEX_GREEN, x, y), 061 image.getSample(INDEX_BLUE, x, y)); 062 } 063 } 064 return result; 065 } 066 067 /** 068 * Creates an RGB24Image from the palette entries, each entry 069 * becomes a pixel in an image of width 1 and height 070 * palette.getNumEntries(). 071 */ 072 public static RGB24Image convertPaletteToImage(Palette palette) 073 { 074 RGB24Image result = new MemoryRGB24Image(1, palette.getNumEntries()); 075 for (int index = 0; index < palette.getNumEntries(); index++) 076 { 077 result.putSample(INDEX_RED, 0, index, palette.getSample(INDEX_RED, index)); 078 result.putSample(INDEX_GREEN, 0, index, palette.getSample(INDEX_GREEN, index)); 079 result.putSample(INDEX_BLUE, 0, index, palette.getSample(INDEX_BLUE, index)); 080 } 081 return result; 082 } 083 084 /** 085 * Loads a palette from the argument file. 086 * Uses {@link net.sourceforge.jiu.codecs.ImageLoader} to load an 087 * image from the argument file, then calls {@link #convertImageToPalette} 088 * and returns the palette created that way. 089 */ 090 public static Palette load(File paletteFile) 091 { 092 PixelImage image; 093 try 094 { 095 image = ImageLoader.load(paletteFile, (Vector)null); 096 } 097 catch (Exception e) 098 { 099 return null; 100 } 101 if (!(image instanceof RGB24Image)) 102 { 103 return null; 104 } 105 return convertImageToPalette((RGB24Image)image); 106 } 107 108 /** 109 * Saves the palette to the given file as a PPM image file. 110 * Uses {@link net.sourceforge.jiu.codecs.PNMCodec}. 111 */ 112 public static void save(Palette palette, File paletteFile) throws 113 IOException 114 { 115 RGB24Image image = convertPaletteToImage(palette); 116 PNMCodec codec = new PNMCodec(); 117 codec.setOutputStream(new FileOutputStream(paletteFile)); 118 codec.setAscii(true); 119 codec.setImage(image); 120 try 121 { 122 codec.process(); 123 } 124 catch(OperationFailedException ofe) 125 { 126 throw new IOException("I/O error: " + ofe.toString()); 127 } 128 } 129 }