The COMES Image Format ---------- CIF is a text-based image format designed to be as shitty and verbose as possible. All CIF images are either 24bpp or 32bpp, as indicated in the header. Colors have 8 bits per channel, so RGB8 and RGBA8 formats are supported. CIF images may have any arbitrary resolution. Common rules ============ .. code-block: ws <- +' ' nl <- +'\n' comma <- ',' * ws semicolon <- ';' * ws colon <- ':' * ws magic <- "CIF" Language-specific keywords ========================== Depending on the language chosen, certain keywords change in the format. Polish ****** .. code-block:: version <- "WERSJA" size <- "ROZMIAR" width <- "szerokość" height <- "wysokość" bpp <- "bitów_na_piksel" metadata <- "METADANE" node <- "WĘZEŁ" branch <- "GAŁĄŹ" leaf <- "LIŚĆ" English ******* .. code-block:: version <- "VERSION" size <- "SIZE" width <- "width" height <- "height" bpp <- "bits_per_pixel" metadata <- "METADATA" node <- "NODE" branch <- "BRANCH" leaf <- "LEAF" Number encoding =============== Number encoding changes depending on flags passed to the coder. compact ******* Compact should be able to parse any arbitrary 64-bit number. .. code-block:: digit <- {'0'..'9'} int <- +digit polish ****** Polish must be able to parse/reproduce numbers at least in the range 0..9999. *PEG code for the ``int`` rule is not included because it quickly gets really verbose. Implementation is an exercise for the reader :)* english ******* English should be able to parse/reproduce numbers at least in the range 0..9999. `fourty` is preferred over `forty`, but both can be implemented for completeness (though `forty` is optional). Image files =========== Common header ************* Every image file has a header which signifies metadata about the image. This header must appear at the very top of the file. .. code-block:: separatedList(sep, rule) <- ?(rule * *(sep * rule)) # Magic + flags must appear at the very first line of the file flag <- "polish" | "english" | "compact" | "quadtree" magicFlags <- magic * colon * separatedList(comma, flag) * nl # Then the version versiondef <- ver * ws * int * nl # Then the image size sizedef <- size * ws * width * colon * int * comma * height * colon * int * comma * bpp * colon * int * nl # Then any number of metadata definitions metakey <- +{'a'..'z', 'A'..'Z', '0'..'9', '_'} metavalue <- *(1 - nl) metadatadef <- metadata * metakey * colon * metavalue * nl metadatadefs <- *metadatadef # This is the rule for the full header: header <- magicFlags * versiondef * sizedef * metadatadefs * nl Pixel format ************ Depending on whether the image is 24bpp or 32bpp, pixels may be encoded in one of two ways: .. code-block:: if bpp == 24: pixel <- int * semicolon * int * semicolon * int elif bpp == 32: pixel <- int * semicolon * int * semicolon * int * semicolon * int Image data ********** Depending on whether quadtree mode is used or not, pixel data may be encoded in one of the following ways: Stream mode ~~~~~~~~~~~ Pixels in stream mode are arranged in top to bottom, left to right order. .. code-block:: imageData <- *(pixel * nl) Quadtree mode ~~~~~~~~~~~~~ When quadtree mode is enabled, while coding the image the read/write buffer must be enlarged to the nearest power of two. Anything out of bounds of the image size is expected to be solid black (0, 0, 0) in 24bpp mode or transparent (0, 0, 0, 0) in 32bpp mode. .. code-block:: # Quadtrees are built out of branch nodes and leaf nodes. # Each branch node has 4 children nodes that may be other branch nodes or # leaf nodes. # Each leaf node encodes a solid pixel color. branchNode <- node * ws * branch * nl * anyNode * nl * anyNode * nl * anyNode * nl * anyNode * nl leafNode <- node * ws * leaf * ws * pixel anyNode <- leafNode | branchNode imageData <- anyNode * nl Tying it all together ********************* Given the previously defined parsing rules, this is how a CIF file should be read: .. code-block:: cif <- header * anyNode