/*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* fbc_gamma_table - Read, pack, and write a gamma table
*/
#include <ctype.h> /* isspace() */
#include <fcntl.h>
#include <stdio.h> /* fclose(), feof(), fgets(), fopen(), ... */
#include <stdlib.h> /* free(), malloc(), strchr(), strtoul() */
#include <string.h> /* strcat(), strcpy(), strlen(), strrchr() */
#include "gfx_gamma_pack.h" /* gfx_pack_gamma_string_16() */
#include "fbc.h" /* Common fbconf_xorg(1M) definitions */
#include "fbc_error.h" /* Error reporting */
#include "fbc_gamma_table.h" /* Read, pack, and write a gamma table table */
/*
* fbc_read_users_gamma_table()
*
* Read a text file containing the user's Red-Green-Blue gamma
* correction value triplets. Return arrays of Red, Green, and Blue
* gamma binary values.
*
* Gamma file syntax:
* <file> =:: <line>...
* <line> =:: [<sp>][<number>[<sp><number>]...]<eol>
* <sp> =:: ' '|'\t'...
* # Whitespace character recognized by isspace()
* <number> =:: <octal_int> | <decimal_int> | <hexadecimal_int>
* # Numeric string recognized by strtoul(,,0)
* <eol> =:: [<comment>]'\n'
* <comment> =:: '#'[<text>]
*
* Gamma file example:
* #
* # Gamma correction table for fictitious FB device
* #
*
* 0x000 0x000 0x000 # 0
* 0x001 0x001 0x001 # 1
* 0x002 0x002 0x002 # 2
* ... ... ... . ...
* 0x3FF 0x3FF 0x3FF # 1023
*
* # End of gamma_file.txt
*/
static
int
const char *gfile_in_path, /* Pathname of input gamma file */
int lut_size, /* Gamma look-up table size */
unsigned short gamma_red[], /* Returned Red gamma values */
unsigned short gamma_green[], /* Returned Green gamma values */
unsigned short gamma_blue[]) /* Returned Blue gamma values */
{
int i; /* RGB array indices */
/*
* Assume no errors
*/
/*
* Open the user's text file containing a gamma correction table
*/
if (gamma_in_stream == NULL) {
fbc_errormsg("Can't open input gamma file, %s\n",
return (FBC_ERR_OPEN);
}
/*
* Read the gamma table, parsing a lut_size number of RGB triplets
*/
line_num = 0;
for (gamma_count = 0; ; ) {
/*
* Get the next non-whitespace, non-comment character
*/
/*
* Read a text line from the gamma file
*/
line_num += 1;
== NULL) {
if (feof(gamma_in_stream) == 0) {
"Error reading gamma file, %s, line %d\n",
break; /* Gamma file input error */
}
/*
* Check for correct # of RGB triplets
*/
if (gamma_count !=
(NUM_COLORS * lut_size)) {
/* Wrong # of gamma values */
"Too few gamma values in file, %s, line %d\n",
}
break; /* End of gamma file */
}
continue;
}
line_ptr += 1;
continue;
}
/*
* Parse the hexadecimal, decimal, or octal value
*/
fbc_errormsg("Invalid gamma value, %s, line %d\n",
break;
}
/*
* Make sure gamma file doesn't contain too many gamma values
*/
i = gamma_count / NUM_COLORS;
if (i >= lut_size) {
"Too many gamma values in file, %s, line %d\n",
break;
}
/*
* Save the Red, Green, or Blue gamma correction value
*/
switch (gamma_count % NUM_COLORS) {
case 0:
gamma_red[i] = (unsigned short)gamma_value;
break;
case 1:
gamma_green[i] = (unsigned short)gamma_value;
break;
case 2:
gamma_blue[i] = (unsigned short)gamma_value;
break;
}
gamma_count += 1;
}
/*
* Close the input gamma file
*/
return (error_code);
} /* fbc_read_users_gamma_table() */
/*
* fbc_read_gamma_table()
*
* Read a text file containing the user's gamma correction table,
* consisting of a lut_size number of Red-Green-Blue triplet values.
* Return pointers to dynamically allocated packed strings of Red,
* Green, and Blue gamma correction values.
*/
int
const char *gfile_in_path, /* Pathname of input gamma file */
int lut_size, /* # of RGB triplets in gamma file */
char **gamma_string_red, /* Returned packed Red values */
char **gamma_string_green, /* Returned packed Green vals */
char **gamma_string_blue) /* Returned packed Blue values */
{
/*
* Show that the strings for packed gamma values aren't allocated yet
*
* Our caller may have done this already, since the caller is
* responsible for releasing the memory.
*/
*gamma_string_red = NULL;
/*
* Allocate arrays for the input gamma table data
*/
if (gt_data_red == NULL) {
return (FBC_ERR_NOMEM);
}
/*
* Read the gamma correction table data from the user's gamma file
*/
if (error_code == FBC_SUCCESS) {
/*
* Pack the gamma correction values into dynamic strings
*/
if ((gfx_pack_gamma_string_16(
/*
* Handle a gamma data packing error
*/
*gamma_string_red = NULL;
fbc_errormsg("Error packing gamma table data, %s\n",
}
}
/*
* Release the input gamma table data arrays
*/
return (error_code);
} /* fbc_read_gamma_table() */
/*
* fbc_build_gamma_table_path()
*
* Construct the output gamma correction table pathname. The
* directory component will be the same as for the configuration
* file. The file name will be unique for the frame buffer device,
* consisting of the device name with a ".gamma" extension.
*/
int
const char *config_file_path, /* Configuration file pathname */
const char *device_name, /* Frame buffer device name */
char *gfile_path_buf, /* Gamma table output pathname buf */
int gfile_path_buf_len) /* Gamma table path buf len */
{
dir_len = 0; /* Case of no directory component */
}
>= gfile_path_buf_len) {
fbc_errormsg("Gamma table pathname is too long\n");
return (FBC_ERR_PATH_LEN);
}
return (FBC_SUCCESS);
} /* fbc_build_gamma_table_path() */
/*
* fbc_write_packed_gamma_table()
*
* Write a packed gamma correction table to a newly created file.
* The file will contain three lines of characters, each ending with
* a Newline character.
*/
int
const char *gfile_out_path, /* Pathname of output gamma file */
char *gamma_string_red, /* Packed Red values string */
char *gamma_string_green, /* Packed Green values string */
char *gamma_string_blue) /* Packed Blue values string */
{
/*
* Delete, create, and open the output packed gamma table file
*/
if (gamma_out_stream == NULL) {
fbc_errormsg("Can't create and open output gamma file, %s\n",
return (FBC_ERR_OPEN);
}
/*
* Write the packed gamma correction table to the file
*/
/*
* Close the new gamma table file
*/
return (FBC_SUCCESS);
} /* fbc_write_packed_gamma_table() */
/*
* fbc_read_packed_gamma_table()
*
* Read the contents of a packed gamma table file into a single
* dynamically allocated buffer. The file should contain three lines
* of characters, each ending with a Newline character. Other than
* the presence of Newlines, no assumptions are made concerning the
* lengths of the lines. Each Newline character is replaced by a
* Nul. Pointers to the three RGB Nul-terminated strings are
* returned.
*/
int
const char *gfile_in_path, /* Pathname of input gamma file */
char **gamma_string_red, /* Returned packed Red values */
char **gamma_string_green, /* Returned packed Green vals */
char **gamma_string_blue) /* Returned packed Blue values */
{
/*
* Measure the gamma file for a new buffer
*/
return (FBC_ERR_STAT);
}
if (*gamma_string_red == NULL) {
return (FBC_ERR_NOMEM);
}
/*
* Open the file containing the packed gamma correction table
*/
if (gamma_in_stream == NULL) {
fbc_errormsg("Can't open input gamma file, %s\n",
goto read_packed_gamma_error;
}
/*
* Read the packed gamma table strings
*/
sizeof (char),
goto read_packed_gamma_error;
}
/*
* Separate the gamma buffer into its component colors and return
*/
if (*gamma_string_green != NULL) {
**gamma_string_green = '\0';
*gamma_string_green += 1;
if (*gamma_string_blue != NULL) {
**gamma_string_blue = '\0';
*gamma_string_blue += 1;
return (FBC_SUCCESS);
}
}
}
/*
* Release the buffer and return unsuccessfully
*/
return (error_code);
} /* fbc_read_packed_gamma_table() */
/*
* fbc_free_gamma_strings()
*
* Free any packed gamma string memory that was allocated by
* gfx_pack_gamma_string_16().
*/
void
char *gamma_string_red, /* Packed Red values string */
char *gamma_string_green, /* Packed Green values string */
char *gamma_string_blue) /* Packed Blue values string */
{
} /* fbc_free_gamma_strings() */
/* End of fbc_gamma_table.c */