fitline.c   [plain text]


/*
cc -o /tmp/fitline fitline.c
*/

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <strings.h>
#include <assert.h>
#include <IOKit/graphics/IOGraphicsTypesPrivate.h>


static uint16_t data[3][256] = {{
#if 0
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
},{
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
},{
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
    0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
#elif 1
// k92
/*    0      1      2      3      4      5      6      7      8      9      A      B      C      D      E      F */
    0x0000,0x002b,0x00c4,0x0129,0x0176,0x01de,0x0241,0x02a9,0x0320,0x039b,0x0423,0x04ac,0x0540,0x05dc,0x068c,0x0749,
    0x080b,0x08e5,0x09bf,0x0aad,0x0bac,0x0cb5,0x0dc3,0x0edd,0x1006,0x1133,0x126f,0x13b5,0x14fc,0x1646,0x179d,0x18f6,
    0x1a50,0x1bab,0x1d06,0x1e5e,0x1fb3,0x210d,0x2265,0x23b4,0x2505,0x2658,0x27a2,0x28ea,0x2a38,0x2b7c,0x2cbf,0x2e00,
    0x2f43,0x3085,0x31c3,0x3303,0x3443,0x3584,0x36bc,0x37f4,0x392b,0x3a5a,0x3b90,0x3cc4,0x3df6,0x3f27,0x4057,0x4186,
    0x42b2,0x43dc,0x4504,0x4629,0x4749,0x4866,0x497f,0x4a95,0x4bab,0x4cbd,0x4dce,0x4edc,0x4fee,0x510c,0x5232,0x5355,
    0x5478,0x559a,0x56bb,0x57da,0x58fa,0x5a1d,0x5b3c,0x5c59,0x5d74,0x5e90,0x5faa,0x60c3,0x61dc,0x62f3,0x640b,0x6524,
    0x6639,0x674a,0x6855,0x6960,0x6a6a,0x6b70,0x6c7a,0x6d80,0x6e83,0x6f87,0x7088,0x7185,0x7284,0x737c,0x7473,0x756a,
    0x7660,0x7752,0x7843,0x7933,0x7a18,0x7af1,0x7bc4,0x7c97,0x7d6e,0x7e46,0x7f21,0x8000,0x80e3,0x81c9,0x82b2,0x83a0,
    0x8491,0x8585,0x8679,0x8773,0x886e,0x896b,0x8a6f,0x8b93,0x8cea,0x8e3a,0x8f88,0x90d2,0x9218,0x9359,0x9499,0x95d2,
    0x9707,0x9839,0x9966,0x9a8e,0x9bba,0x9cde,0x9e03,0x9f27,0xa04e,0xa176,0xa29c,0xa3c1,0xa4e3,0xa608,0xa72b,0xa84e,
    0xa970,0xaa92,0xabb2,0xacce,0xadec,0xaf09,0xb026,0xb140,0xb25b,0xb375,0xb48f,0xb5a9,0xb6c6,0xb7e2,0xb8ff,0xba1a,
    0xbb35,0xbc4d,0xbd61,0xbe74,0xbf85,0xc096,0xc1a5,0xc2ae,0xc3ba,0xc4c6,0xc5d4,0xc6dd,0xc7e5,0xc8ed,0xc9e5,0xcad8,
    0xcbc5,0xccb2,0xcd9a,0xce7e,0xcf5e,0xd03b,0xd115,0xd1ef,0xd2c3,0xd399,0xd46e,0xd540,0xd612,0xd6e4,0xd7ae,0xd873,
    0xd934,0xd9f4,0xdaaf,0xdb66,0xdc1b,0xdccf,0xdd81,0xde32,0xdee4,0xdf96,0xe04b,0xe103,0xe1bb,0xe276,0xe337,0xe400,
    0xe4cd,0xe597,0xe660,0xe728,0xe7ef,0xe8b2,0xe971,0xea2e,0xeaea,0xeba2,0xec59,0xed0d,0xedbe,0xee70,0xef23,0xefdc,
    0xf09f,0xf169,0xf23a,0xf312,0xf3f4,0xf4e2,0xf5db,0xf6e2,0xf7f5,0xf914,0xfa3f,0xfb73,0xfcb0,0xfdf2,0xff25,0xffff,
},{
    0x0000,0x001d,0x0083,0x0111,0x0157,0x01b7,0x021e,0x0276,0x02e0,0x034c,0x03c1,0x0442,0x04cf,0x0563,0x0602,0x06ae,
    0x0766,0x0827,0x08f0,0x09ce,0x0ab5,0x0ba8,0x0ca0,0x0da3,0x0eb3,0x0fcd,0x10f4,0x1219,0x1348,0x1479,0x15b1,0x16e9,
    0x1828,0x1962,0x1aa2,0x1bda,0x1d17,0x1e54,0x1f87,0x20bd,0x21f1,0x2325,0x244f,0x257b,0x26a4,0x27cb,0x28ed,0x2a10,
    0x2b31,0x2c53,0x2d70,0x2e8d,0x2fad,0x30c8,0x31e0,0x32f8,0x340f,0x3522,0x363a,0x374d,0x3863,0x3974,0x3a83,0x3b93,
    0x3ca2,0x3dae,0x3eb8,0x3fbf,0x40c3,0x41c5,0x42c3,0x43c0,0x44bc,0x45b5,0x46ac,0x47a2,0x489c,0x49a3,0x4ab1,0x4bbf,
    0x4cca,0x4dd6,0x4ee1,0x4feb,0x50f4,0x5200,0x530b,0x5412,0x551a,0x5622,0x5727,0x582e,0x5933,0x5a38,0x5b3e,0x5c45,
    0x5d48,0x5e47,0x5f40,0x6038,0x6130,0x6227,0x631f,0x6416,0x650d,0x6604,0x66f9,0x67ef,0x68e4,0x69d8,0x6acc,0x6bc1,
    0x6cb7,0x6daa,0x6e9e,0x6f8f,0x7078,0x7146,0x720d,0x72d4,0x739e,0x746c,0x7538,0x7607,0x76da,0x77af,0x7886,0x795d,
    0x7a36,0x7b11,0x7bec,0x7cca,0x7daa,0x7e89,0x7f68,0x8055,0x8157,0x8261,0x836d,0x8476,0x857f,0x8687,0x8793,0x889e,
    0x89a7,0x8ab0,0x8bbc,0x8cc7,0x8dd1,0x8edd,0x8fe8,0x90f3,0x9200,0x9310,0x9421,0x9532,0x9641,0x9753,0x9866,0x9976,
    0x9a85,0x9b96,0x9ca6,0x9db4,0x9ebf,0x9fcc,0xa0d6,0xa1e1,0xa2e9,0xa3ef,0xa4f9,0xa60a,0xa729,0xa84c,0xa971,0xaa9a,
    0xabc1,0xacea,0xae10,0xaf3d,0xb06a,0xb197,0xb2c6,0xb3f7,0xb528,0xb65c,0xb78f,0xb8c1,0xb9f4,0xbb20,0xbc43,0xbd64,
    0xbe84,0xbf9c,0xc0af,0xc1c1,0xc2cb,0xc3ce,0xc4d0,0xc5c8,0xc6be,0xc7b1,0xc8a2,0xc98f,0xca7b,0xcb67,0xcc55,0xcd42,
    0xce2c,0xcf14,0xcff9,0xd0d9,0xd1b5,0xd290,0xd36b,0xd444,0xd51d,0xd5f8,0xd6d3,0xd7b2,0xd892,0xd974,0xda5a,0xdb43,
    0xdc2f,0xdd1b,0xde0a,0xdefa,0xdfec,0xe0e0,0xe1d5,0xe2cb,0xe3c5,0xe4c1,0xe5be,0xe6be,0xe7bc,0xe8bd,0xe9be,0xeabf,
    0xebc3,0xeccd,0xede5,0xef06,0xf034,0xf172,0xf2bc,0xf416,0xf583,0xf6fd,0xf885,0xfa18,0xfbb5,0xfd57,0xfefe,0xffff,
},{
    0x0000,0x0056,0x0114,0x0165,0x01de,0x0234,0x0285,0x02e7,0x0346,0x03ac,0x041d,0x048e,0x050b,0x0589,0x0612,0x06a4,
    0x073e,0x07de,0x0886,0x0938,0x09f6,0x0ab6,0x0b80,0x0c53,0x0d2d,0x0e0d,0x0ef2,0x0fe2,0x10cf,0x11c3,0x12c1,0x13cd,
    0x14dd,0x15ef,0x1704,0x1818,0x1928,0x1a40,0x1b52,0x1c65,0x1d77,0x1e87,0x1f95,0x20a4,0x21b3,0x22bf,0x23c9,0x24d3,
    0x25df,0x26e9,0x27f0,0x28f8,0x2a00,0x2b08,0x2c08,0x2cff,0x2df1,0x2edf,0x2fd0,0x30c0,0x31af,0x329d,0x3389,0x3475,
    0x355e,0x3646,0x372b,0x380f,0x38ef,0x39d1,0x3aae,0x3b89,0x3c64,0x3d3f,0x3e19,0x3ef0,0x3fc9,0x40a3,0x417f,0x425f,
    0x433f,0x441e,0x4502,0x45e4,0x46c7,0x47aa,0x488d,0x4972,0x4a55,0x4b3b,0x4c1d,0x4d00,0x4de2,0x4ec2,0x4fa3,0x5084,
    0x5166,0x524e,0x533b,0x5424,0x550c,0x55ef,0x56ce,0x57aa,0x5884,0x5958,0x5a2a,0x5afc,0x5bcc,0x5c9b,0x5d69,0x5e3a,
    0x5f0b,0x5fdd,0x60b1,0x618a,0x6265,0x632a,0x63e5,0x649d,0x6559,0x661a,0x66df,0x67aa,0x6879,0x694d,0x6a25,0x6b01,
    0x6bdd,0x6cbb,0x6d99,0x6e74,0x6f4e,0x7027,0x70fd,0x71cb,0x7290,0x7353,0x7417,0x74da,0x759c,0x765d,0x7720,0x77e2,
    0x78a3,0x7963,0x7a25,0x7ae6,0x7ba6,0x7c67,0x7d27,0x7de8,0x7eaa,0x7f73,0x804e,0x8130,0x8211,0x82f5,0x83da,0x84be,
    0x85a2,0x8687,0x876c,0x8850,0x8932,0x8a14,0x8af6,0x8bd6,0x8cb4,0x8d91,0x8e6f,0x8f51,0x9035,0x911e,0x920b,0x92fa,
    0x93ed,0x94e2,0x95d7,0x96d4,0x97d4,0x98d5,0x99d9,0x9ae0,0x9be9,0x9cf5,0x9dff,0x9f09,0xa01c,0xa13f,0xa26e,0xa39d,
    0xa4ce,0xa601,0xa734,0xa867,0xa99b,0xaac9,0xabf2,0xad16,0xae36,0xaf50,0xb064,0xb174,0xb281,0xb38e,0xb4a3,0xb5be,
    0xb6d6,0xb7ec,0xb900,0xba12,0xbb22,0xbc34,0xbd49,0xbe62,0xbf81,0xc0a6,0xc1d4,0xc30a,0xc447,0xc58d,0xc6d6,0xc80b,
    0xc935,0xca5f,0xcb8c,0xccbc,0xcdf0,0xcf29,0xd061,0xd1a0,0xd2de,0xd41e,0xd55c,0xd69c,0xd7da,0xd918,0xda58,0xdba1,
    0xdcf6,0xde59,0xdfd0,0xe15c,0xe308,0xe4d8,0xe6d4,0xe909,0xeb74,0xee12,0xf0e7,0xf3e3,0xf71d,0xfa6f,0xfddf,0xffff,
#elif 0
    0x0000,0x0101,0x0202,0x0303,0x0404,0x0505,0x0606,0x0707,0x0808,0x0909,0x0a0a,0x0b0b,0x0c0c,0x0d0d,0x0e0e,0x0f0f,
    0x1010,0x1111,0x1212,0x1313,0x1414,0x1515,0x1616,0x1717,0x1818,0x1919,0x1a1a,0x1b1b,0x1c1c,0x1d1d,0x1e1e,0x1f1f,
    0x2020,0x2121,0x2222,0x2323,0x2424,0x2525,0x2626,0x2727,0x2828,0x2929,0x2a2a,0x2b2b,0x2c2c,0x2d2d,0x2e2e,0x2f2f,
    0x3030,0x3131,0x3232,0x3333,0x3434,0x3535,0x3636,0x3737,0x3838,0x3939,0x3a3a,0x3b3b,0x3c3c,0x3d3d,0x3e3e,0x3f3f,
    0x4040,0x4141,0x4242,0x4343,0x4444,0x4545,0x4646,0x4747,0x4848,0x4949,0x4a4a,0x4b4b,0x4c4c,0x4d4d,0x4e4e,0x4f4f,
    0x5050,0x5151,0x5252,0x5353,0x5454,0x5555,0x5656,0x5757,0x5858,0x5959,0x5a5a,0x5b5b,0x5c5c,0x5d5d,0x5e5e,0x5f5f,
    0x6060,0x6161,0x6262,0x6363,0x6464,0x6565,0x6666,0x6767,0x6868,0x6969,0x6a6a,0x6b6b,0x6c6c,0x6d6d,0x6e6e,0x6f6f,
    0x7070,0x7171,0x7272,0x7373,0x7474,0x7575,0x7676,0x7777,0x7878,0x7979,0x7a7a,0x7b7b,0x7c7c,0x7d7d,0x7e7e,0x7f7f,
    0x8080,0x8181,0x8282,0x8383,0x8484,0x8585,0x8686,0x8787,0x8888,0x8989,0x8a8a,0x8b8b,0x8c8c,0x8d8d,0x8e8e,0x8f8f,
    0x9090,0x9191,0x9292,0x9393,0x9494,0x9595,0x9696,0x9797,0x9898,0x9999,0x9a9a,0x9b9b,0x9c9c,0x9d9d,0x9e9e,0x9f9f,
    0xa0a0,0xa1a1,0xa2a2,0xa3a3,0xa4a4,0xa5a5,0xa6a6,0xa7a7,0xa8a8,0xa9a9,0xaaaa,0xabab,0xacac,0xadad,0xaeae,0xafaf,
    0xb0b0,0xb1b1,0xb2b2,0xb3b3,0xb4b4,0xb5b5,0xb6b6,0xb7b7,0xb8b8,0xb9b9,0xbaba,0xbbbb,0xbcbc,0xbdbd,0xbebe,0xbfbf,
    0xc0c0,0xc1c1,0xc2c2,0xc3c3,0xc4c4,0xc5c5,0xc6c6,0xc7c7,0xc8c8,0xc9c9,0xcaca,0xcbcb,0xcccc,0xcdcd,0xcece,0xcfcf,
    0xd0d0,0xd1d1,0xd2d2,0xd3d3,0xd4d4,0xd5d5,0xd6d6,0xd7d7,0xd8d8,0xd9d9,0xdada,0xdbdb,0xdcdc,0xdddd,0xdede,0xdfdf,
    0xe0e0,0xe1e1,0xe2e2,0xe3e3,0xe4e4,0xe5e5,0xe6e6,0xe7e7,0xe8e8,0xe9e9,0xeaea,0xebeb,0xecec,0xeded,0xeeee,0xefef,
    0xf0f0,0xf1f1,0xf2f2,0xf3f3,0xf4f4,0xf5f5,0xf6f6,0xf7f7,0xf8f8,0xf9f9,0xfafa,0xfbfb,0xfcfc,0xfdfd,0xfefe,0xffff,
},{
    0x0000,0x0101,0x0202,0x0303,0x0404,0x0505,0x0606,0x0707,0x0808,0x0909,0x0a0a,0x0b0b,0x0c0c,0x0d0d,0x0e0e,0x0f0f,
    0x1010,0x1111,0x1212,0x1313,0x1414,0x1515,0x1616,0x1717,0x1818,0x1919,0x1a1a,0x1b1b,0x1c1c,0x1d1d,0x1e1e,0x1f1f,
    0x2020,0x2121,0x2222,0x2323,0x2424,0x2525,0x2626,0x2727,0x2828,0x2929,0x2a2a,0x2b2b,0x2c2c,0x2d2d,0x2e2e,0x2f2f,
    0x3030,0x3131,0x3232,0x3333,0x3434,0x3535,0x3636,0x3737,0x3838,0x3939,0x3a3a,0x3b3b,0x3c3c,0x3d3d,0x3e3e,0x3f3f,
    0x4040,0x4141,0x4242,0x4343,0x4444,0x4545,0x4646,0x4747,0x4848,0x4949,0x4a4a,0x4b4b,0x4c4c,0x4d4d,0x4e4e,0x4f4f,
    0x5050,0x5151,0x5252,0x5353,0x5454,0x5555,0x5656,0x5757,0x5858,0x5959,0x5a5a,0x5b5b,0x5c5c,0x5d5d,0x5e5e,0x5f5f,
    0x6060,0x6161,0x6262,0x6363,0x6464,0x6565,0x6666,0x6767,0x6868,0x6969,0x6a6a,0x6b6b,0x6c6c,0x6d6d,0x6e6e,0x6f6f,
    0x7070,0x7171,0x7272,0x7373,0x7474,0x7575,0x7676,0x7777,0x7878,0x7979,0x7a7a,0x7b7b,0x7c7c,0x7d7d,0x7e7e,0x7f7f,
    0x8080,0x8181,0x8282,0x8383,0x8484,0x8585,0x8686,0x8787,0x8888,0x8989,0x8a8a,0x8b8b,0x8c8c,0x8d8d,0x8e8e,0x8f8f,
    0x9090,0x9191,0x9292,0x9393,0x9494,0x9595,0x9696,0x9797,0x9898,0x9999,0x9a9a,0x9b9b,0x9c9c,0x9d9d,0x9e9e,0x9f9f,
    0xa0a0,0xa1a1,0xa2a2,0xa3a3,0xa4a4,0xa5a5,0xa6a6,0xa7a7,0xa8a8,0xa9a9,0xaaaa,0xabab,0xacac,0xadad,0xaeae,0xafaf,
    0xb0b0,0xb1b1,0xb2b2,0xb3b3,0xb4b4,0xb5b5,0xb6b6,0xb7b7,0xb8b8,0xb9b9,0xbaba,0xbbbb,0xbcbc,0xbdbd,0xbebe,0xbfbf,
    0xc0c0,0xc1c1,0xc2c2,0xc3c3,0xc4c4,0xc5c5,0xc6c6,0xc7c7,0xc8c8,0xc9c9,0xcaca,0xcbcb,0xcccc,0xcdcd,0xcece,0xcfcf,
    0xd0d0,0xd1d1,0xd2d2,0xd3d3,0xd4d4,0xd5d5,0xd6d6,0xd7d7,0xd8d8,0xd9d9,0xdada,0xdbdb,0xdcdc,0xdddd,0xdede,0xdfdf,
    0xe0e0,0xe1e1,0xe2e2,0xe3e3,0xe4e4,0xe5e5,0xe6e6,0xe7e7,0xe8e8,0xe9e9,0xeaea,0xebeb,0xecec,0xeded,0xeeee,0xefef,
    0xf0f0,0xf1f1,0xf2f2,0xf3f3,0xf4f4,0xf5f5,0xf6f6,0xf7f7,0xf8f8,0xf9f9,0xfafa,0xfbfb,0xfcfc,0xfdfd,0xfefe,0xffff,
},{
    0x0000,0x0101,0x0202,0x0303,0x0404,0x0505,0x0606,0x0707,0x0808,0x0909,0x0a0a,0x0b0b,0x0c0c,0x0d0d,0x0e0e,0x0f0f,
    0x1010,0x1111,0x1212,0x1313,0x1414,0x1515,0x1616,0x1717,0x1818,0x1919,0x1a1a,0x1b1b,0x1c1c,0x1d1d,0x1e1e,0x1f1f,
    0x2020,0x2121,0x2222,0x2323,0x2424,0x2525,0x2626,0x2727,0x2828,0x2929,0x2a2a,0x2b2b,0x2c2c,0x2d2d,0x2e2e,0x2f2f,
    0x3030,0x3131,0x3232,0x3333,0x3434,0x3535,0x3636,0x3737,0x3838,0x3939,0x3a3a,0x3b3b,0x3c3c,0x3d3d,0x3e3e,0x3f3f,
    0x4040,0x4141,0x4242,0x4343,0x4444,0x4545,0x4646,0x4747,0x4848,0x4949,0x4a4a,0x4b4b,0x4c4c,0x4d4d,0x4e4e,0x4f4f,
    0x5050,0x5151,0x5252,0x5353,0x5454,0x5555,0x5656,0x5757,0x5858,0x5959,0x5a5a,0x5b5b,0x5c5c,0x5d5d,0x5e5e,0x5f5f,
    0x6060,0x6161,0x6262,0x6363,0x6464,0x6565,0x6666,0x6767,0x6868,0x6969,0x6a6a,0x6b6b,0x6c6c,0x6d6d,0x6e6e,0x6f6f,
    0x7070,0x7171,0x7272,0x7373,0x7474,0x7575,0x7676,0x7777,0x7878,0x7979,0x7a7a,0x7b7b,0x7c7c,0x7d7d,0x7e7e,0x7f7f,
    0x8080,0x8181,0x8282,0x8383,0x8484,0x8585,0x8686,0x8787,0x8888,0x8989,0x8a8a,0x8b8b,0x8c8c,0x8d8d,0x8e8e,0x8f8f,
    0x9090,0x9191,0x9292,0x9393,0x9494,0x9595,0x9696,0x9797,0x9898,0x9999,0x9a9a,0x9b9b,0x9c9c,0x9d9d,0x9e9e,0x9f9f,
    0xa0a0,0xa1a1,0xa2a2,0xa3a3,0xa4a4,0xa5a5,0xa6a6,0xa7a7,0xa8a8,0xa9a9,0xaaaa,0xabab,0xacac,0xadad,0xaeae,0xafaf,
    0xb0b0,0xb1b1,0xb2b2,0xb3b3,0xb4b4,0xb5b5,0xb6b6,0xb7b7,0xb8b8,0xb9b9,0xbaba,0xbbbb,0xbcbc,0xbdbd,0xbebe,0xbfbf,
    0xc0c0,0xc1c1,0xc2c2,0xc3c3,0xc4c4,0xc5c5,0xc6c6,0xc7c7,0xc8c8,0xc9c9,0xcaca,0xcbcb,0xcccc,0xcdcd,0xcece,0xcfcf,
    0xd0d0,0xd1d1,0xd2d2,0xd3d3,0xd4d4,0xd5d5,0xd6d6,0xd7d7,0xd8d8,0xd9d9,0xdada,0xdbdb,0xdcdc,0xdddd,0xdede,0xdfdf,
    0xe0e0,0xe1e1,0xe2e2,0xe3e3,0xe4e4,0xe5e5,0xe6e6,0xe7e7,0xe8e8,0xe9e9,0xeaea,0xebeb,0xecec,0xeded,0xeeee,0xefef,
    0xf0f0,0xf1f1,0xf2f2,0xf3f3,0xf4f4,0xf5f5,0xf6f6,0xf7f7,0xf8f8,0xf9f9,0xfafa,0xfbfb,0xfcfc,0xfdfd,0xfefe,0xffff,
#else
// k99
/*  0      1      2      3      4      5      6      7      8      9      A      B      C      D      E      F */
    0x0000,0x0056,0x012e,0x01eb,0x02c4,0x0383,0x0441,0x0507,0x05da,0x06ae,0x078c,0x086f,0x0951,0x0a36,0x0b2c,0x0c16,
    0x0d2c,0x0e45,0x0f57,0x106e,0x118a,0x12b0,0x13d7,0x14fd,0x1627,0x1752,0x1883,0x19b9,0x1aec,0x1c29,0x1d61,0x1ea5,
    0x1ff1,0x2136,0x2282,0x23cc,0x2518,0x2661,0x27ad,0x28f7,0x2a46,0x2b93,0x2ce2,0x2e30,0x2f7d,0x30c8,0x3212,0x3358,
    0x349e,0x35e3,0x3726,0x3866,0x39a2,0x3ade,0x3c1a,0x3d4f,0x3e84,0x3fb6,0x40e8,0x4216,0x4347,0x4457,0x4564,0x4672,
    0x477d,0x4886,0x498d,0x4a93,0x4b98,0x4c99,0x4d9a,0x4e9a,0x4f99,0x5098,0x5197,0x5296,0x5399,0x549d,0x55a0,0x56a4,
    0x57a6,0x58a7,0x59a9,0x5aaa,0x5baa,0x5caa,0x5da9,0x5ea7,0x5fa6,0x60a5,0x61a1,0x629b,0x6394,0x648b,0x6582,0x6678,
    0x676c,0x6860,0x6952,0x6a43,0x6b35,0x6c25,0x6d16,0x6e06,0x6ef6,0x6fe5,0x70d4,0x71c2,0x72b1,0x739f,0x748d,0x757a,
    0x7666,0x7752,0x783c,0x7925,0x7a0e,0x7af5,0x7bdb,0x7cc1,0x7da6,0x7e8b,0x7f70,0x8057,0x8140,0x822b,0x831a,0x840d,
    0x8506,0x8605,0x870a,0x8815,0x8925,0x8a3b,0x8b56,0x8c73,0x8d7e,0x8e87,0x8f90,0x9099,0x91a1,0x92a8,0x93af,0x94b5,
    0x95bb,0x96c1,0x97c8,0x98ce,0x99d4,0x9adb,0x9be4,0x9cf5,0x9e06,0x9f16,0xa025,0xa131,0xa23a,0xa341,0xa447,0xa549,
    0xa64b,0xa74c,0xa84c,0xa94b,0xaa4b,0xab4d,0xac57,0xad64,0xae70,0xaf7c,0xb087,0xb191,0xb29a,0xb3a2,0xb4a7,0xb5ad,
    0xb6b1,0xb7b5,0xb8b7,0xb9ba,0xbabb,0xbbc3,0xbccb,0xbdd2,0xbed9,0xbfe0,0xc0e7,0xc1ed,0xc2f2,0xc3f7,0xc4fb,0xc5ff,
    0xc702,0xc804,0xc906,0xca0a,0xcb16,0xcc25,0xcd36,0xce48,0xcf5c,0xd070,0xd186,0xd29c,0xd3b2,0xd4c8,0xd5dd,0xd6f0,
    0xd802,0xd913,0xda1d,0xdb16,0xdc07,0xdcf6,0xdde2,0xdecc,0xdfb5,0xe09c,0xe184,0xe26c,0xe356,0xe442,0xe531,0xe622,
    0xe716,0xe806,0xe8d2,0xe9a2,0xea78,0xeb52,0xec2f,0xed0e,0xedf0,0xeed2,0xefb4,0xf095,0xf176,0xf255,0xf331,0xf409,
    0xf4dd,0xf5a7,0xf668,0xf719,0xf7ab,0xf814,0xf851,0xf88e,0xf8cb,0xf90f,0xf961,0xf9b3,0xfa1b,0xfaf0,0xfca7,0xffff,
},{
    0x0000,0x0056,0x0145,0x0228,0x02d1,0x0383,0x0441,0x0506,0x05c6,0x0698,0x0769,0x0839,0x0914,0x09ec,0x0ac5,0x0bae,
    0x0cb2,0x0dbe,0x0ed4,0x0fe8,0x10f5,0x120f,0x132d,0x1445,0x1561,0x1681,0x17a4,0x18ca,0x19f4,0x1b19,0x1c41,0x1d7d,
    0x1ebc,0x1ff9,0x2137,0x2271,0x23b2,0x24f1,0x262e,0x276d,0x28ad,0x29ef,0x2b2d,0x2c70,0x2db0,0x2ef2,0x3028,0x3160,
    0x3297,0x33cd,0x3502,0x3636,0x3765,0x3893,0x39c0,0x3aee,0x3c18,0x3d42,0x3e6a,0x3f93,0x40b2,0x41bc,0x42bd,0x43bc,
    0x44bb,0x45b9,0x46b5,0x47b0,0x48aa,0x49a2,0x4a99,0x4b8f,0x4c83,0x4d77,0x4e6b,0x4f5f,0x5055,0x514d,0x5242,0x533a,
    0x5430,0x5526,0x561c,0x5712,0x5807,0x58fd,0x59f3,0x5ae8,0x5bde,0x5cd3,0x5dc6,0x5eb7,0x5fa7,0x6096,0x6185,0x6274,
    0x6361,0x644e,0x653b,0x6627,0x6713,0x67fe,0x68ea,0x69d5,0x6ac0,0x6bab,0x6c92,0x6d7a,0x6e61,0x6f48,0x702e,0x7115,
    0x71fb,0x72e1,0x73c6,0x74ab,0x7590,0x7675,0x7758,0x783d,0x7920,0x7a03,0x7ae7,0x7bcb,0x7cb1,0x7d98,0x7e81,0x7f6d,
    0x805b,0x814c,0x823e,0x8334,0x842b,0x8524,0x861e,0x871b,0x881e,0x8923,0x8a28,0x8b2d,0x8c32,0x8d37,0x8e3c,0x8f40,
    0x9045,0x914a,0x9250,0x9356,0x945b,0x9561,0x9669,0x977c,0x9890,0x99a3,0x9ab5,0x9bc5,0x9cd5,0x9de1,0x9eec,0x9ff6,
    0xa0fe,0xa204,0xa30a,0xa40f,0xa513,0xa61c,0xa730,0xa84a,0xa962,0xaa79,0xab8e,0xaca3,0xadb5,0xaec5,0xafd2,0xb0df,
    0xb1ea,0xb2f4,0xb3fc,0xb505,0xb610,0xb726,0xb840,0xb959,0xba72,0xbb8a,0xbca0,0xbdb4,0xbec7,0xbfd9,0xc0e9,0xc1f9,
    0xc307,0xc415,0xc521,0xc634,0xc756,0xc87f,0xc9a8,0xcad2,0xcbfb,0xcd25,0xce4f,0xcf78,0xd0a0,0xd1c9,0xd2f1,0xd418,
    0xd53f,0xd665,0xd789,0xd8a4,0xd9ba,0xdac9,0xdbd3,0xdcd7,0xddd6,0xded0,0xdfc6,0xe0bc,0xe1b0,0xe2a4,0xe39a,0xe492,
    0xe58d,0xe689,0xe77e,0xe869,0xe952,0xea3e,0xeb2d,0xec1e,0xed10,0xee03,0xeef4,0xefe2,0xf0cb,0xf1ae,0xf28d,0xf365,
    0xf43e,0xf51d,0xf5fd,0xf6b7,0xf75d,0xf7f9,0xf885,0xf912,0xf9a6,0xfa45,0xfaf0,0xfbbb,0xfc9e,0xfd9e,0xfebe,0xffff,
},{
    0x0000,0x0056,0x0123,0x01b0,0x024c,0x02f0,0x0396,0x0440,0x04e3,0x0583,0x062d,0x06dd,0x0791,0x084a,0x0904,0x09bf,
    0x0a7f,0x0b44,0x0c0d,0x0cd7,0x0da3,0x0e73,0x0f47,0x1021,0x10f6,0x11d1,0x12ae,0x138d,0x1471,0x1561,0x165c,0x1756,
    0x1850,0x194c,0x1a45,0x1b41,0x1c3c,0x1d37,0x1e31,0x1f2c,0x2029,0x2123,0x2220,0x231d,0x2415,0x2512,0x260e,0x270a,
    0x2803,0x28fe,0x29f8,0x2af3,0x2bed,0x2ce6,0x2de0,0x2ed9,0x2fce,0x30b6,0x3197,0x3279,0x335a,0x343b,0x351a,0x35f9,
    0x36d8,0x37b5,0x3891,0x396c,0x3a45,0x3b1e,0x3bf3,0x3cc8,0x3d9c,0x3e6e,0x3f3f,0x400d,0x40db,0x41a8,0x4273,0x4340,
    0x4408,0x44d1,0x4599,0x4662,0x4729,0x47ef,0x48b2,0x4973,0x4a34,0x4af4,0x4bb6,0x4c78,0x4d3a,0x4dfb,0x4ebd,0x4f80,
    0x5042,0x5105,0x51c8,0x528b,0x534e,0x5411,0x54d4,0x5598,0x565c,0x571e,0x57e2,0x58a6,0x596a,0x5a2e,0x5af1,0x5bb5,
    0x5c79,0x5d3c,0x5dfc,0x5ebd,0x5f7e,0x603f,0x60fe,0x61bf,0x627f,0x633f,0x63fe,0x64be,0x657e,0x663d,0x66fd,0x67bc,
    0x687b,0x693b,0x69fa,0x6ab9,0x6b78,0x6c37,0x6cf7,0x6db6,0x6e76,0x6f36,0x6ff5,0x70b4,0x7175,0x7233,0x72ef,0x73aa,
    0x7466,0x7522,0x75df,0x769d,0x775c,0x781b,0x78dc,0x799d,0x7a61,0x7b26,0x7bec,0x7cb4,0x7d7e,0x7e49,0x7f16,0x7fe5,
    0x80b5,0x8187,0x8259,0x832d,0x8403,0x84d8,0x85af,0x8687,0x875f,0x8837,0x8914,0x89f8,0x8ade,0x8bc5,0x8cac,0x8d93,
    0x8e7b,0x8f64,0x904d,0x9138,0x9225,0x9313,0x9404,0x94f7,0x95ec,0x96e5,0x97e0,0x98df,0x99e0,0x9ae5,0x9bed,0x9cf7,
    0x9e05,0x9f14,0xa027,0xa13d,0xa255,0xa36e,0xa488,0xa599,0xa69b,0xa79d,0xa8a0,0xa9a6,0xaaae,0xabb8,0xacc5,0xadd4,
    0xaee7,0xaffd,0xb116,0xb232,0xb353,0xb478,0xb5a0,0xb6cc,0xb7fd,0xb932,0xba69,0xbba4,0xbce3,0xbe25,0xbf69,0xc0af,
    0xc1fa,0xc346,0xc494,0xc5e4,0xc741,0xc8aa,0xca25,0xcbae,0xcd44,0xcee8,0xd099,0xd258,0xd423,0xd5fa,0xd7df,0xd9ce,
    0xdbca,0xddd3,0xdfe7,0xe207,0xe435,0xe66d,0xe8b2,0xeb03,0xed64,0xefd0,0xf24e,0xf4dc,0xf77e,0xfa36,0xfd07,0xffff,
#endif
}};

#if 0
function DouglasPeucker(PointList[], epsilon)
 //Find the point with the maximum distance
 dmax = 0
 index = 0
 for i = 2 to (length(PointList) - 1)
  d = PerpendicularDistance(PointList[i], Line(PointList[1], PointList[end])) 
  if d > dmax
   index = i
   dmax = d
  end
 end
 
 //If max distance is greater than epsilon, recursively simplify
 if dmax >= epsilon
  //Recursive call
  recResults1[] = DouglasPeucker(PointList[1...index], epsilon)
  recResults2[] = DouglasPeucker(PointList[index...end], epsilon)
  
  // Build the result list
  ResultList[] = {recResults1[1...end-1] recResults2[1...end]}
 else
  ResultList[] = {PointList[1], PointList[end]}
 end
 
 //Return the result
 return ResultList[]
end
#endif


enum { kIOFBGammaPointCountMax = 100 };
enum { kIOFBGammaDesiredError = 255 };

struct IOFBLineSeg
{
	// [start end]
    uint16_t start;
    uint16_t end;
    uint16_t dist;
    uint16_t split;
};
typedef struct IOFBLineSeg IOFBLineSeg;

static void IOFBSegDist(const uint16_t data[], IOFBLineSeg * seg)
{
	uint16_t start;
	uint16_t end;
	uint16_t idx;
	uint16_t interp;
	int16_t  dist;

	seg->dist  = 0;
	start = seg->start;
	end   = seg->end;
	for (idx = start + 1; idx < end; idx++)
	{
		interp = data[start] + ((data[end] - data[start]) * (idx - start)) / (end - start);
		dist = data[idx] - interp;
		if (dist < 0) dist = -dist;
		if (dist > seg->dist)
		{
			seg->dist = dist;
			seg->split = idx;
		}
	}
}

static void IOFBSegInit(const uint16_t data[],
					IOFBLineSeg * seg, uint16_t start, uint16_t end)
{
	seg->start = start;
	seg->end   = end;
	IOFBSegDist(data, seg);
}

static void
IOFBSimplifySegs(const uint16_t data[], 
				uint16_t desiredError, uint16_t * maxError, 
				IOFBLineSeg * segs, uint16_t count, uint16_t maxCount,
				IOFBBootGamma * bootGamma)
{
	IOFBGamma * channelGamma;
	uint16_t    idx;
	uint16_t    furthest;

	while (count < maxCount)
	{
		furthest = 0;
		for (idx = 1; idx < count; idx++)
		{
			if (segs[idx].dist > segs[furthest].dist) furthest = idx;
		}
		if (segs[furthest].dist <= desiredError) break;
		bcopy(&segs[furthest+1], &segs[furthest+2], (count - furthest - 1) * sizeof(IOFBLineSeg));
		count++;
		assert ((furthest+1) < maxCount);
		IOFBSegInit(data, &segs[furthest+1], segs[furthest].split, segs[furthest].end);
		segs[furthest].end = segs[furthest].split;
		IOFBSegDist(data, &segs[furthest]);
	}

	*maxError = 0;
	channelGamma = &bootGamma->gamma.red;
	for (idx = 0; idx < count; idx++)
	{
		if (segs[idx].dist > *maxError) 
		{
			*maxError = segs[idx].dist;
//printf("max error seg 0x%x, 0x%x count %d, target %d\n", segs[idx].start, segs[idx].end, count, maxCount);
		}
		if (!(segs[idx].start & 255))
		{
			if (segs[idx].start)
			{
				channelGamma = (typeof(channelGamma)) &channelGamma->points[channelGamma->pointCount];
			}
			channelGamma->pointCount = 0;
			continue;
		}
		channelGamma->points[channelGamma->pointCount].in = 
							(segs[idx].start & 0xFF) | ((segs[idx].start & 0xFF) << 8);
		channelGamma->points[channelGamma->pointCount].out = data[segs[idx].start];
		channelGamma->pointCount++;
	}
}

static bool 
IOFBCompressGamma(
	IOFBBootGamma * bootGamma,
    uint16_t channelCount, uint16_t srcDataCount,
    uint16_t dataWidth, const void * _data,
    uint16_t desiredError, uint16_t maxCount,
    uint16_t * maxError)
{
	IOFBGamma * channelGamma;
	const uint16_t * data = (typeof(data)) _data;
	uint16_t idx;

	if ((3 != channelCount) || (16 != dataWidth)) return (false);

	data = (typeof(data)) _data;

	IOFBLineSeg * segs;
	maxCount += 3;
	segs = malloc(maxCount * sizeof(IOFBLineSeg));
	memset(segs, 0xee, maxCount * sizeof(IOFBLineSeg));

	IOFBSegInit(data, &segs[0],   0, 255);
	IOFBSegInit(data, &segs[1], 256, 511);
	IOFBSegInit(data, &segs[2], 512, 767);

	IOFBSimplifySegs(data, desiredError, maxError,
					segs, 3, maxCount,
					bootGamma);
	free(segs);

	channelGamma = &bootGamma->gamma.red;
	for (idx = 0; idx < channelCount; idx++)
	{
		channelGamma = (typeof(channelGamma)) &channelGamma->points[channelGamma->pointCount];
	}
	bootGamma->length = ((uintptr_t) channelGamma) - ((uintptr_t) bootGamma);
	return (true);
}

void IOFBDecompressGamma(const IOFBBootGamma * bootGamma, uint16_t * data, uint16_t count)
{
	const IOFBGamma * channelGamma;
	uint16_t channel, idx, maxIdx, seg;
	uint16_t startIn, startOut;
	uint16_t endIn, endOut;

	maxIdx = count - 1;
	channelGamma = &bootGamma->gamma.red;
	for (channel = 0; channel < 3; channel++)
	{
		seg = 0;
		startIn = 0;
		startOut = 0x0000;
		endIn = 0;
		endOut = 0;
		for (idx = 0; idx <= maxIdx; idx++)
		{
			if ((idx == endIn) && (idx != maxIdx))
			{
				startIn = endIn;
				startOut = endOut;
				if (seg < channelGamma->pointCount)
				{
					endIn = (channelGamma->points[seg].in * count) >> 16;
					endOut = channelGamma->points[seg].out;
					seg++;
				}
				else
				{
					endIn = maxIdx;
					endOut = 0xFFFF;
				}
			}
			data[channel * count + idx] = startOut + ((endOut - startOut) * (idx - startIn)) / (endIn - startIn);
		}
		channelGamma = (typeof(channelGamma)) &channelGamma->points[channelGamma->pointCount];
	}
}


int main(int argc, char * argv[])
{
	IOFBBootGamma * bootGamma;
	uint16_t desiredError = kIOFBGammaDesiredError;
	uint16_t maxCount = kIOFBGammaPointCountMax;
	uint16_t maxError;

	if (argc > 2)
	{
		desiredError = strtol(argv[1], 0, 0);
		maxCount = strtol(argv[2], 0, 0);
	}

	bootGamma = (typeof(bootGamma)) malloc(sizeof(IOFBBootGamma) 
					+ (maxCount * sizeof(IOFBGammaPoint)));
	memset(bootGamma, 0xee, sizeof(IOFBBootGamma) + (maxCount * sizeof(IOFBGammaPoint)));

	bootGamma->vendor  = 0;
	bootGamma->product = 0;
	bootGamma->serial  = 0;
	if (IOFBCompressGamma(bootGamma, 3, 256, 16, &data[0][0], desiredError, maxCount, &maxError))
	{
		fprintf(stderr, "compressed gamma to 0x%x bytes, maxError 0x%04x\n", bootGamma->length, maxError);

		IOFBGamma * channelGamma;
		uint16_t idx, j, channel;

		channelGamma = &bootGamma->gamma.red;
		for (idx = 0; idx < 3; idx++)
		{
			for (j = 0; j < channelGamma->pointCount; j++) fprintf(stderr, "[%d,%02d] 0x%04x 0x%04x\n", idx, j, channelGamma->points[j].in, channelGamma->points[j].out);
			channelGamma = (typeof(channelGamma)) &channelGamma->points[channelGamma->pointCount];
		}

		uint16_t * deco;
		uint16_t count = 1024;
		deco = (typeof(deco)) malloc(sizeof(uint16_t) * 3 * count);
		IOFBDecompressGamma(bootGamma, deco, count);

		uint16_t maxError = 0;
		uint16_t maxErrorIdx;
		for (channel = 0; channel < 3; channel++)
		{
			for (idx = 0; idx < count; idx++)
			{
				printf("0x%04x 0x%04x\n",
					deco[channel * count + idx], data[channel][idx >> 2]);

				if (idx & 3) continue;

				int16_t error = (deco[channel * count + idx] - data[channel][idx >> 2]);
				if (error < 0) error = -error;
				if (error > maxError)
				{
					maxErrorIdx = idx;
					maxError = error;
				}
			}
		}
		free(deco);
		fprintf(stderr, "maxError 0x%04x @ 0x%x\n", maxError, maxErrorIdx);

	}
	free(bootGamma);

	return (0);
}