/**
   * Hides the given message inside the specified image.
   *
   * <p>The image will be given to you as a GImage of some size, and the message will be specified
   * as a boolean array of pixels, where each white pixel is denoted false and each black pixel is
   * denoted true.
   *
   * <p>The message should be hidden in the image by adjusting the red channel of all the pixels in
   * the original image. For each pixel in the original image, you should make the red channel an
   * even number if the message color is white at that position, and odd otherwise.
   *
   * <p>You can assume that the dimensions of the message and the image are the same.
   *
   * <p>
   *
   * @param message The message to hide.
   * @param source The source image.
   * @return A GImage whose pixels have the message hidden within it.
   */
  public static GImage hideMessage(boolean[][] message, GImage source) {
    int[][] pixels = source.getPixelArray();

    for (int row = 0; row < pixels.length; row++) {
      for (int col = 0; col < pixels[row].length; col++) {
        /* Extract the green and blue components and write them back, changing the
         * red component.
         */
        int red = GImage.getRed(pixels[row][col]);
        int green = GImage.getGreen(pixels[row][col]);
        int blue = GImage.getBlue(pixels[row][col]);
        if (message[row][col]) {
          if (red % 2 == 0) { // If the secret pixel is black, make the red channel odd
            red++;
          }
        } else {
          if (red % 2 != 0) { // If the secret pixel is white, make the red channel even
            red++;
          }
          if (red > 255) {
            red -= 2;
          }
        }

        pixels[row][col] = GImage.createRGBPixel(red, green, blue);
      }
    }
    return new GImage(pixels);
  }
  public static int[][] imageToLuminances(int[][] pixels) {
    int[][] luminances = new int[pixels.length][pixels[0].length];

    for (int row = 0; row < pixels.length; ++row) {
      for (int col = 0; col < pixels[row].length; ++col) {
        luminances[row][col] = GImage.getRed(pixels[row][col]);
      }
    }

    return luminances;
  }
  private static int redToEven(int pixel) { // в НЕЧЕТНЫЙ
    int oldRed = GImage.getRed(pixel);
    int newRed;

    if (oldRed % 2 == 1) { // нечетный
      newRed = oldRed;
    } else { // если четный
      newRed = oldRed + 1;
    }

    return GImage.createRGBPixel(
        newRed, GImage.getGreen(pixel), GImage.getBlue(pixel), GImage.getAlpha(pixel));
  }
  /**
   * Given a GImage containing a hidden message, finds the hidden message contained within it and
   * returns a boolean array containing that message.
   *
   * <p>A message has been hidden in the input image as follows. For each pixel in the image, if
   * that pixel has a red component that is an even number, the message value at that pixel is
   * false. If the red component is an odd number, the message value at that pixel is true.
   *
   * @param source The image containing the hidden message.
   * @return The hidden message, expressed as a boolean array.
   */
  public static boolean[][] findMessage(GImage source) {
    int[][] image = source.getPixelArray();

    boolean[][] result = new boolean[image.length][image[0].length];

    for (int i = 0; i < image.length; i++) {
      for (int j = 0; j < image[0].length; j++) {
        result[i][j] = ((GImage.getRed(image[i][j]) % 2) != 0);
      }
    }

    return result;
  }
 /**
  * Given a GImage containing a hidden message, finds the hidden message contained within it and
  * returns a boolean array containing that message.
  *
  * <p>A message has been hidden in the input image as follows. For each pixel in the image, if
  * that pixel has a red component that is an even number, the message value at that pixel is
  * false. If the red component is an odd number, the message value at that pixel is true.
  *
  * @param source The image containing the hidden message.
  * @return The hidden message, expressed as a boolean array.
  */
 public static boolean[][] findMessage(GImage source) {
   int[][] pixels = source.getPixelArray();
   boolean[][] bwImage = new boolean[pixels.length][];
   for (int row = 0; row < pixels.length; row++) {
     bwImage[row] = new boolean[pixels[row].length];
     for (int col = 0; col < pixels[row].length; col++) {
       int red = GImage.getRed(pixels[row][col]);
       bwImage[row][col] =
           red % 2 == 0
               ? false
               : true; // recover the hidden message by returning a boolean[][] containing the
                       // pixels of the hidden image
     }
   }
   return bwImage;
 }
  public static GImage toGrayscale(GImage image) {
    int[][] pixels = image.getPixelArray();

    for (int row = 0; row < pixels.length; ++row) {
      for (int col = 0; col < pixels[row].length; ++col) {
        int intensity =
            (int)
                (0.3D * (double) GImage.getRed(pixels[row][col])
                    + 0.59D * (double) GImage.getGreen(pixels[row][col])
                    + 0.11D * (double) GImage.getBlue(pixels[row][col])
                    + 0.5D);
        pixels[row][col] = GImage.createRGBPixel(intensity, intensity, intensity);
      }
    }

    return new GImage(pixels);
  }