<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.imageio.*;
import java.net.*;
import java.io.*;


/** An instance contains 
 (1) an original image (of class RmoaImage),
 (2) a possibly altered (by methods in this instance) version of the original image,
 (3) methods to process the image
 */
public class ImageProcessor {
    
    /** DM provides methods for extracting components of an rgb pixel. */
    public static final DirectColorModel DM= (DirectColorModel) ColorModel.getRGBdefault();
    
    /** The following four constants of this class indicate a color.*/
    /** Color gray */
    public static final int GRAY= 0;
    
    /** Color red */
    public static final int RED= 1;
    
    /** Color green */
    public static final int GREEN= 2;
    
    /** Color blue */
    public static final int BLUE= 3;
    
    private RmoaImage originalIm; // The original image, for restoration purposes
    private RmoaImage currentIm;  // The altered image
    
    /** Constructor: an instance for im.
        Precondition: im != null. */
    public ImageProcessor(RmoaImage im) {
        originalIm= im;
        currentIm= originalIm.copy();
    }
    
    /** = the current image. */
    public RmoaImage getCurrentImage() {
        return currentIm;
    }
    
    /** = the original image. */
    public RmoaImage getOriginalImage() {
        return originalIm;
    }
    
    /** Invert the current image, replacing each element with its color complement. */
    public void invert() {
        int len= currentIm.getRows() * currentIm.getCols();
        
        // invert all pixels (leave alpha/transparency value alone)
        
        // invariant: pixels 0..p-1 have been complemented.
        for (int p= 0; p &lt; len; p= p+1) {
                int rgb= currentIm.getPixel(p);
                int red= 255 - DM.getRed(rgb);
                int blue= 255 - DM.getBlue(rgb);
                int green= 255 - DM.getGreen(rgb);
                int alpha= DM.getAlpha(rgb);
                currentIm.setPixel(p,
                              (alpha &lt;&lt; 24) | (red &lt;&lt; 16) | (green &lt;&lt; 8) | blue);
        }
    }
    
    /** Transpose the current image.  */
    public void transpose() {
        /* Write this method, following the plan shown below. Then delete this
           comment. Also, place the comments used below in 
           appropriate places in the method body, as statement-comments, to
           indicate what the various parts of the method body are doing. If
           you don't do this, you will lose points. */
        
        
        // (1) Create a new RmoaImage b, using currentIM's row-major order array
        //     and rows and columns, but swap the roles of its numbers
        //     of rows and columns.
        // (2) Store the transpose of the currentIm array in b, using currentIm's
        //     2-parameter getPixel function and b's 3-parameter setPixel
        //     function.
        // (3) assign b to currentIm.
        
        
    }
    
    /** Reflect the current image around the horizontal middle. */
    public void hreflect() {
        int rows= currentIm.getRows();
        int cols= currentIm.getCols();
        int h= 0;
        int k= rows-1;
        //invariant: rows 0..h-1 and k+1.. have been inverted
        while (h &lt; k) {
            // Swap row h with row k
            // invariant: pixels 0..c-1 of rows h and k have been swapped
            for (int c= 0; c != cols; c= c+1) {
                currentIm.swapPixels(h, c, k, c);
            }
            
            h= h+1; k= k-1;
        }
    }
    
    /** Reflect the current image around the vertical middle. */
    public void vreflect() {
        /* Write the body of this method. Then delete this comment,
           of you will lose points. */
        
        
    }
    
    /* Filter the current image to be only a single color, which is given by
     parameter color.&lt;br&gt;&lt;br&gt;
     
     Precondition: color is one of the four color constants GRAY,
     RED, GREEN, BLUE of this class.&lt;br&gt;&lt;br&gt;
     
     Gray is achieved by making all three color components equal to the
     average of the red, green, and blue components. For the other three
     colors, make the non-used components 0.
     
     The alpha component is not changed.
     */
    public void filter(int color) {
        /* Write the body of this method. Then delete this comment,
           of you will lose points. */
    }
    
    /** Hide message m in the current image, using the ascii representation of m's chars.
        Return true if this is possible and false if not.
        If m has more than 999999 characters or the picture doesn't have enough
          pixels, return false without storing the message.
     */
    public boolean hide(String m) {
        /** Replace the return statement below by the method body that
            implements the specification. Then remove this comment; if you
            don't do this, you will lose points.
            
            If you add new functions, make them private; the user should not
            be able to use them. You can alsodefine a private, static class if
            you need to, in order to "aggregate" several variables into one
            object and provide methods that operate on them. But this generally
            is not necessary. Speak to a TA or instructor if you feel the need
            for this, just to make sure you know what you are doing.
            */
        return false;
    }
    
    /** Extract and return the message hidden in the current image.
        Return null if no message detected. */
    public String reveal() {
           /* Write the body of this method. Then delete this comment,
           of you will lose points. */
        return null;
    }
    
    
    /** Restore the original image in the current one */
    public void restore() {
        currentIm= originalIm.copy();
    }
    
    /** Provided file fname does not appear in the current directory, store the
       current image in file fname in the current directory, as a jpg file.
       Write a message on the console indicating whether or not the write was successful. */
    public void writeImage(String fname) throws java.io.IOException {
      File f= new File(fname);
      if (f.exists()) {
          System.out.println("File " + f.getAbsolutePath() + " exists. It was not overwritten.");
          return;
      }
      
      int r= currentIm.getRows();
      int c= currentIm.getCols();
      int roa[]= currentIm.getRmoArray();
      
      // Create an image from roa. The new Container is needed to get an
      // object that has the appropriate function, createImage, in it; that is all.
      Image image= (new Container()).createImage(new MemoryImageSource(c, r, roa, 0, c));
      
      // Obtain a buffered image and the graphics for it. It has to have the right width and height.
      // The third arg of the call below indicates that input into it will be an integer array of
      // rgb colors
      BufferedImage bimage= 
          new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
      Graphics g= bimage.createGraphics();
      
      
      // put the image into bimage so that it can be written out and dispose of the graphics.
      g.drawImage(image, 0, 0, null);
      g.dispose();
      
      // Finally, write the image onto the file and give the appropriate message
      ImageIO.write(bimage, "jpg", f);
      System.out.println("Image written to " + f.getAbsolutePath());
    }  
    
}
</pre></body></html>