Announcement

Collapse
No announcement yet.

PKM file support

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Requested PKM file support

    I would like to open/save in PKM image format too. I've atached GrafX 2.00 Beta 96.5% (the freeware program who use and created this file format)

    !WARNING! instead of 0..255 (888) it uses values from 0..63 (555)

    Here is the file format from the doc's:

    The PKM picture format - by Karl Maritaud

    First of all, I'd like to say that I made this file format some years ago when I didn't knew how to load any good format (eg. GIF) and wanted to have my own format.
    PKM format was designed to be very simple, easy to encode and decode. Its header is very simple (short) and evolutive.
    The only real default I can find in this format is that you can only save 256-color pictures.
    I know that you will think:
    "Oh no just another fucking format! I'll never use it! Its compression is too poor and I prefer GIF!".
    And I'll answer:
    "Yeah! You're right. But if you dunno how to load GIF and want a simple format with a quite good compression rate (on simple pictures at least), it could be useful."

    So, here comes the format documentation...


    The HEADER:

    The header is the following 780-byte-structure. (Don't worry about the size.
    That's just because the palette is considered as a part of the header).



    Data of type "word" are stored with Intel conventions: lower byte first.

    The POST-HEADER:

    The post-header has a variable size. It was designed to support new features for this file format without changing the whole format.

    It consists in field identifiers followed by their size and their value.
    A field identifier is coded with 1 byte and a field size also.


    These field identifiers are: (this list may be updated...)

    0 : Comment on the picture
    1 : Original screen dimensions
    2 : Back color (transparent color)

    If you encounter a field that you don't know just jump over it. But if a field tells you to jump to a position that is over the beginning of the picture data, there is an error in the file.

    The fields:
    • Comment:
      With this field, artists will be able to comment their pictures.
      Note that GrafX 2 has a comment size limit of 32 chars. But you can comment a picture with up to 255 chars if you make your own viewer since GrafX 2 will just ignore extra characters.

      Example: [0],[16],[Picture by X-Man]
      This sequence means:
      - the field is a comment
      - the comment takes 16 characters (there is no end-of-string character since you know its size)
      - the comment is "Picture by X-Man"

    • Original screen dimensions:
      Since GrafX 2 supplies a huge range of resolutions, it seemed convenient to add a field that indicates what were the original screen dimensions.

      Example: [1],[4],[320],[256]
      This sequence means:
      - the field is a screen dimensions descriptor
      - the dimensions are 2 words (so this value must be always equal to 4)
      - the original screen width was 320 pixels
      - the original screen height was 256 pixels

      Note that words stored in fields are written Intel-like. The 90% BETA version did not respect this norm. I'm really sorry about this. This is not very serious but pictures saved with version 90% and loaded with a latest version (91% and more) won't set the right resolution.

    • Back color:
      Saving the back color (transparent color) is especially useful when you want to save a brush.
      The size of this field is 1 byte (index of the color between 0 and 255).

      Example: [2],[1],[255]
      This sequence means:
      - the field is a screen dimensions descriptor
      - the value takes 1 byte
      - the transparent color is 255



    The PICTURE PACKING METHOD:

    The PKM compression method is some sort of Run-Length-Compression which is very efficient on pictures with long horizontal color repetitions.
    Actually, the compression is efficient if there are often more than 3 times the same color consecutively.

    I think that it would be better to give you the algorithm instead of swimming in incomprehensible explanations.

    Code:
    BEGIN
      /*
        functions:
          Read_byte(File)       reads and returns 1 byte from File
          Draw_pixel(X,Y,Color) draws a pixel of a certain Color at pos. (X,Y)
          File_length(File)     returns the total length in bytes of File
    
        variables:
          type of Image_size          is dword
          type of Data_size           is dword
          type of Packed_data_counter is dword
          type of Pixels_counter      is dword
          type of Color               is byte
          type of Byte_read           is byte
          type of Word_read           is word
          type of Counter             is word
          type of File                is <binary file>
      */
    
      /* At this point you've already read the header and post-header. */
    
      Image_size          <- Header.Width * Header.Height
      Data_size           <- File_length(File) - (780+Header.PH_size)
    
      Packed_data_counter <- 0
      Pixels_counter      <- 0
    
      /* Depacking loop: */
      WHILE ((Pixels_counter<Image_size) AND (Packed_data_counter<Data_size)) DO
      {
        Byte_read <- Read_byte(File)
    
        /* If it is not a packet recognizer, it's a raw pixel */
        IF ((Byte_read<>Header.Pack_byte) AND (Byte_read<>Header.Pack_word))
        THEN
        {
          Draw_pixel(Pixels_counter MOD Header.Width,
                     Pixels_counter DIV Header.Width,
                     Byte_read)
    
          Pixels_counter      <- Pixels_counter + 1
          Packed_data_counter <- Packed_data_counter + 1
        }
        ELSE /* Is the number of pixels to repeat coded... */
        {    /* ... with 1 byte */
          IF (Byte_read = Header.Pack_byte) THEN
          {
            Color     <- Read_byte(File)
            Byte_read <- Read_byte(File)
    
            FOR Counter FROM 0 TO (Byte_read-1) STEP +1
              Draw_pixel((Pixels_counter+Counter) MOD Header.Width,
                         (Pixels_counter+Counter) DIV Header.Width,
                         Color)
    
            Pixels_counter      <- Pixels_counter + Byte_read
            Packed_data_counter <- Packed_data_counter + 3
          }
          ELSE /* ... with 2 bytes */
          {
            Color     <- Read_byte(File)
            Word_read <- (word value) (Read_byte(File) SHL 8)+Read_byte(File)
    
            FOR Counter FROM 0 TO (Word_read-1) STEP +1
              Draw_pixel((Pixels_counter+Counter) MOD Header.Width,
                         (Pixels_counter+Counter) DIV Header.Width,
                         Color)
    
            Pixels_counter      <- Pixels_counter + Word_read
            Packed_data_counter <- Packed_data_counter + 4
          }
        }
      }
    END
    For example, the following sequence:
    (we suppose that Pack_byte=01 and Pack_word=02)
    04 03 01 05 06 03 02 00 01 2C
    will be decoded as:
    04 03 05 05 05 05 05 05 03 00 00 00 ... (repeat 0 300 times (012Ch=300))

    Repetitions that fit in a word must be written with their higher byte first.
    I know that it goes against Intel standard but since I read bytes from the file thru a buffer (really faster), I don't care about the order (Sorry ).
    But words in the header and post-header must be written and read Intel-like!


    Packing advices:
    • As you can see, there could be a problem when you'd want to pack a raw pixel with a color equal to Pack_byte or Pack_word. These pixels should always be coded as a packet even if there is only one pixel.

      Example: (we suppose that Pack_byte=9)
      9 will be encoded 9,9,1 (The 1st 9 in the encoded...
      9,9 will be encoded 9,9,2 ... sequence is Pack_byte)
      etc...
    • It seems obvious to find values for Pack_byte and Pack_word that are (almost) never used. So a small routine that finds the 2 less used colors in the image should be called before starting to pack the picture. This can be done almost instantaneously in Assembler.

    • When you want to pack a 2-color-sequence, just write these 2 colors one after the other (Color,Color) because it only takes 2 bytes instead of 3 if you had to write a packet (Pack_byte,Color,2).

    • If you pack a very simple picture which has a sequence of more than 65535 same consecutive bytes, you must break the sequence and continue with a new packet.


    Example: you have to pack 65635 same consecutive bytes (eg. color 0)
    (we suppose that Pack_byte=01 and Pack_word=02)
    You'll write: 02 00 FF FF 01 00 64 (FFFFh=65535, 64h=100)
    Here are the images included in package saved with GFX2 in PKM format plus TEST.PKM and TEST2.PKM.
    TEST.PKM is a converted file saved with my Screen Convertor (tool for converting from/to screen$ format used by ZX-Spectrum computers and later by emulators on PC). This file is uncompressed! Yes, it's possible if you have at least 2 unused colors. I use #FE and #FF as markers, colors unused in image
    TEST2.PKM is my file saved by GFX2 (compressed format)
    Attached Files
    Last edited by Jaff; 08.12.2007, 12:34 AM. Reason: added some sample pictures
    Imi este indiferent ce cred ceilalti despre mine, caci oricum fiecare crede ce-i convine lui si nu ceea ce e real,
    doar ca mi-ar fi placut sa ma vada asa cum sint de fapt, nu asa cum poate le-ar placea lor sa creada. Ei au ales deja...

    ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷··
    ·· · ·M· · ·I· · ·D· · ·I· · ·· ·· ·M· · ·A· · ·N· · ·I· · ·A· · ·C· · ·S· · ··
    ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷··

    #2
    Great news! Grafix v2.4 is out! (01 oct. 2012)
    PKM format specs
    Imi este indiferent ce cred ceilalti despre mine, caci oricum fiecare crede ce-i convine lui si nu ceea ce e real,
    doar ca mi-ar fi placut sa ma vada asa cum sint de fapt, nu asa cum poate le-ar placea lor sa creada. Ei au ales deja...

    ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷··
    ·· · ·M· · ·I· · ·D· · ·I· · ·· ·· ·M· · ·A· · ·N· · ·I· · ·A· · ·C· · ·S· · ··
    ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷·· ·· · · · ·· ··÷¦÷··

    Comment


      #3
      This is a non-starter. Why on earth should Irfan add support for an image format that no one uses, and hardly anyone has ever heard of?
      Before you post ... Edit your profile • IrfanView 4.62 • Windows 10 Home 19045.2486

      Irfan PaintIrfan View HelpIrfanPaint HelpRiot.dllMore SkinsFastStone CaptureUploads

      Comment

      Working...
      X