All files / src/lib/tiles readFileToTiles.ts

79.63% Statements 43/54
0% Branches 0/1
83.33% Functions 5/6
79.55% Lines 35/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 12525x 25x 25x 25x             25x                 25x       62x 62x 62x 62x     62x                       25x     2x 2x 2x 2x 2x 2x 2x 4x 10x                 10x 10x     2x               25x     41x 41x 41x 41x 41x 654x 18358x                 18358x     41x               25x                                            
import { TILE_SIZE } from "consts";
import { readFile } from "fs-extra";
import { PNG } from "pngjs";
import {
  ImageIndexFunction,
  IndexedImage,
  indexedImageTo2bppTileData,
  pixelDataToIndexedImage,
  sliceIndexedImage,
} from "shared/lib/tiles/indexedImage";
import { tileDataIndexFn } from "shared/lib/tiles/tileData";
 
/**
 * Load the given PNG image filename into an IndexedImage using the supplied index function.
 *
 * @param filename A local filename which is read using the NodeJS readFile method
 * @param indexFn Function to map an individual RGB pixel value to an 8-bit indexed value
 * @returns A new IndexedImage representing the image data provided
 */
export const readFileToIndexedImage = async (
  filename: string,
  indexFn: ImageIndexFunction
): Promise<IndexedImage> => {
  const fileData = await readFile(filename);
  return new Promise((resolve, reject) => {
    new PNG().parse(fileData, (err, data) => {
      Iif (err) {
        return reject(err);
      }
      resolve(
        pixelDataToIndexedImage(data.width, data.height, data.data, indexFn)
      );
    });
  });
};
 
/**
 * Read an image filename into a GB 2bpp data array
 * @param filename Tiles image filename
 * @returns Uint8Array of 2bpp tile data
 */
export const readFileToTilesData = async (
  filename: string
): Promise<Uint8Array> => {
  const img = await readFileToIndexedImage(filename, tileDataIndexFn);
  const xTiles = Math.floor(img.width / TILE_SIZE);
  const yTiles = Math.floor(img.height / TILE_SIZE);
  const size = xTiles * yTiles * 16;
  const output = new Uint8Array(size);
  let index = 0;
  for (let tyi = 0; tyi < yTiles; tyi++) {
    for (let txi = 0; txi < xTiles; txi++) {
      const tileData = indexedImageTo2bppTileData(
        sliceIndexedImage(
          img,
          txi * TILE_SIZE,
          tyi * TILE_SIZE,
          TILE_SIZE,
          TILE_SIZE
        )
      );
      output.set(tileData, index);
      index += tileData.length;
    }
  }
  return output;
};
 
/**
 * Read an image filename into an array of GB 2bpp data array (one array per tile)
 * @param filename Tiles image filename
 * @returns Array of Uint8Array of 2bpp tile data
 */
export const readFileToTilesDataArray = async (
  filename: string
): Promise<Uint8Array[]> => {
  const img = await readFileToIndexedImage(filename, tileDataIndexFn);
  const xTiles = Math.floor(img.width / TILE_SIZE);
  const yTiles = Math.floor(img.height / TILE_SIZE);
  const output = [];
  for (let tyi = 0; tyi < yTiles; tyi++) {
    for (let txi = 0; txi < xTiles; txi++) {
      const tileData = indexedImageTo2bppTileData(
        sliceIndexedImage(
          img,
          txi * TILE_SIZE,
          tyi * TILE_SIZE,
          TILE_SIZE,
          TILE_SIZE
        )
      );
      output.push(tileData);
    }
  }
  return output;
};
 
/**
 * Convert an indexed image into an array of GB 2bpp data array (one array per tile)
 * @param filename Tiles image filename
 * @returns Array of Uint8Array of 2bpp tile data
 */
export const indexedImageToTilesDataArray = (
  img: IndexedImage
): Uint8Array[] => {
  const xTiles = Math.floor(img.width / TILE_SIZE);
  const yTiles = Math.floor(img.height / TILE_SIZE);
  const output = [];
  for (let tyi = 0; tyi < yTiles; tyi++) {
    for (let txi = 0; txi < xTiles; txi++) {
      const tileData = indexedImageTo2bppTileData(
        sliceIndexedImage(
          img,
          txi * TILE_SIZE,
          tyi * TILE_SIZE,
          TILE_SIZE,
          TILE_SIZE
        )
      );
      output.push(tileData);
    }
  }
  return output;
};