This commit is contained in:
twinaphex 2016-06-03 07:53:23 +02:00
parent db2e701cfe
commit 06b9b3790a
11 changed files with 412 additions and 201 deletions

View File

@ -289,26 +289,26 @@ static void arm_enable_runfast_mode(void)
#if defined(__linux__) && !defined(CPU_X86)
static unsigned char check_arm_cpu_feature(const char* feature)
{
char line[1024];
unsigned char status = 0;
FILE *fp = fopen("/proc/cpuinfo", "r");
RFILE *fp = filestream_open("/proc/cpuinfo", RFILE_MODE_READ_TEXT, -1);
if (fp)
if (!fp)
return 0;
while (filestream_gets(fp, line, sizeof(line)) != NULL)
{
char line[1024];
if (strncmp(line, "Features\t: ", 11))
continue;
while (fgets(line , sizeof(line) , fp) != NULL)
{
if (strncmp(line, "Features\t: ", 11))
continue;
if (strstr(line + 11, feature) != NULL)
status = 1;
if (strstr(line + 11, feature) != NULL)
status = 1;
break;
}
fclose(fp);
break;
}
filestream_close(fp);
return status;
}

View File

@ -451,7 +451,7 @@ static int file_archive_decompress_data_to_file(
}
end:
if (handle->data)
if (handle && handle->data)
free(handle->data);
return ret;
}

View File

@ -76,12 +76,12 @@ struct config_file
struct config_include_list *includes;
};
static config_file_t *config_file_new_internal(const char *path, unsigned depth);
void config_file_free(config_file_t *conf);
static config_file_t *config_file_new_internal(
const char *path, unsigned depth);
static char *getaline(FILE *file)
{
char* newline = (char*)malloc(9);
char* newline = (char*)malloc(9);
char* newline_tmp = NULL;
size_t cur_size = 8;
size_t idx = 0;
@ -113,6 +113,45 @@ static char *getaline(FILE *file)
return newline;
}
static char *strip_comment(char *str)
{
/* Remove everything after comment.
* Keep #s inside string literals. */
char *string_end = str + strlen(str);
bool cut_comment = true;
while (!string_is_empty(str))
{
char *comment = NULL;
char *literal = strchr(str, '\"');
if (!literal)
literal = string_end;
comment = (char*)strchr(str, '#');
if (!comment)
comment = string_end;
if (cut_comment && literal < comment)
{
cut_comment = false;
str = literal + 1;
}
else if (!cut_comment && literal)
{
cut_comment = true;
str = literal + 1;
}
else if (comment)
{
*comment = '\0';
str = comment;
}
else
str = string_end;
}
return str;
}
static char *extract_value(char *line, bool is_value)
{
char *save = NULL;
@ -153,6 +192,27 @@ static char *extract_value(char *line, bool is_value)
return NULL;
}
static void add_include_list(config_file_t *conf, const char *path)
{
struct config_include_list *head = conf->includes;
struct config_include_list *node = (struct config_include_list*)calloc(1, sizeof(*node));
if (!node)
return;
node->path = strdup(path);
if (head)
{
while (head->next)
head = head->next;
head->next = node;
}
else
conf->includes = node;
}
static void set_list_readonly(struct config_entry_list *list)
{
while (list)
@ -196,27 +256,6 @@ static void add_child_list(config_file_t *parent, config_file_t *child)
parent->tail = NULL;
}
static void add_include_list(config_file_t *conf, const char *path)
{
struct config_include_list *head = conf->includes;
struct config_include_list *node = (struct config_include_list*)calloc(1, sizeof(*node));
if (!node)
return;
node->path = strdup(path);
if (head)
{
while (head->next)
head = head->next;
head->next = node;
}
else
conf->includes = node;
}
static void add_sub_conf(config_file_t *conf, char *line)
{
char real_path[PATH_MAX_LENGTH] = {0};
@ -259,45 +298,6 @@ static void add_sub_conf(config_file_t *conf, char *line)
free(path);
}
static char *strip_comment(char *str)
{
/* Remove everything after comment.
* Keep #s inside string literals. */
char *strend = str + strlen(str);
bool cut_comment = true;
while (!string_is_empty(str))
{
char *comment = NULL;
char *literal = strchr(str, '\"');
if (!literal)
literal = strend;
comment = (char*)strchr(str, '#');
if (!comment)
comment = strend;
if (cut_comment && literal < comment)
{
cut_comment = false;
str = literal + 1;
}
else if (!cut_comment && literal)
{
cut_comment = true;
str = literal + 1;
}
else if (comment)
{
*comment = '\0';
str = comment;
}
else
str = strend;
}
return str;
}
static bool parse_line(config_file_t *conf,
struct config_entry_list *list, char *line)
{
@ -371,23 +371,6 @@ static bool parse_line(config_file_t *conf,
return true;
}
bool config_append_file(config_file_t *conf, const char *path)
{
config_file_t *new_conf = config_file_new(path);
if (!new_conf)
return false;
if (new_conf->tail)
{
new_conf->tail->next = conf->entries;
conf->entries = new_conf->entries; /* Pilfer. */
new_conf->entries = NULL;
}
config_file_free(new_conf);
return true;
}
static config_file_t *config_file_new_internal(
const char *path, unsigned depth)
{
@ -430,26 +413,24 @@ static config_file_t *config_file_new_internal(
line = getaline(file);
if (line)
{
if (parse_line(conf, list, line))
{
if (conf->entries)
conf->tail->next = list;
else
conf->entries = list;
conf->tail = list;
}
free(line);
}
else
if (!line)
{
free(list);
continue;
}
if (parse_line(conf, list, line))
{
if (conf->entries)
conf->tail->next = list;
else
conf->entries = list;
conf->tail = list;
}
free(line);
if (list != conf->tail)
free(list);
}
@ -464,6 +445,65 @@ error:
return NULL;
}
void config_file_free(config_file_t *conf)
{
struct config_include_list *inc_tmp = NULL;
struct config_entry_list *tmp = NULL;
if (!conf)
return;
tmp = conf->entries;
while (tmp)
{
struct config_entry_list *hold = NULL;
if (tmp->key)
free(tmp->key);
if (tmp->value)
free(tmp->value);
tmp->value = NULL;
tmp->key = NULL;
hold = tmp;
tmp = tmp->next;
if (hold)
free(hold);
}
inc_tmp = (struct config_include_list*)conf->includes;
while (inc_tmp)
{
struct config_include_list *hold = NULL;
free(inc_tmp->path);
hold = (struct config_include_list*)inc_tmp;
inc_tmp = inc_tmp->next;
free(hold);
}
if (conf->path)
free(conf->path);
free(conf);
}
bool config_append_file(config_file_t *conf, const char *path)
{
config_file_t *new_conf = config_file_new(path);
if (!new_conf)
return false;
if (new_conf->tail)
{
new_conf->tail->next = conf->entries;
conf->entries = new_conf->entries; /* Pilfer. */
new_conf->entries = NULL;
}
config_file_free(new_conf);
return true;
}
config_file_t *config_file_new_from_string(const char *from_string)
{
size_t i;
@ -522,46 +562,6 @@ config_file_t *config_file_new(const char *path)
return config_file_new_internal(path, 0);
}
void config_file_free(config_file_t *conf)
{
struct config_include_list *inc_tmp = NULL;
struct config_entry_list *tmp = NULL;
if (!conf)
return;
tmp = conf->entries;
while (tmp)
{
struct config_entry_list *hold = NULL;
if (tmp->key)
free(tmp->key);
if (tmp->value)
free(tmp->value);
tmp->value = NULL;
tmp->key = NULL;
hold = tmp;
tmp = tmp->next;
if (hold)
free(hold);
}
inc_tmp = (struct config_include_list*)conf->includes;
while (inc_tmp)
{
struct config_include_list *hold = NULL;
free(inc_tmp->path);
hold = (struct config_include_list*)inc_tmp;
inc_tmp = inc_tmp->next;
free(hold);
}
if (conf->path)
free(conf->path);
free(conf);
}
static struct config_entry_list *config_get_entry(const config_file_t *conf,
const char *key, struct config_entry_list **prev)

View File

@ -61,6 +61,7 @@ enum png_chunk_type
PNG_CHUNK_IHDR,
PNG_CHUNK_IDAT,
PNG_CHUNK_PLTE,
PNG_CHUNK_tRNS,
PNG_CHUNK_IEND
};
@ -121,6 +122,7 @@ struct rpng
bool has_idat;
bool has_iend;
bool has_plte;
bool has_trns;
struct idat_buffer idat_buf;
struct png_ihdr ihdr;
uint8_t *buff_data;
@ -144,6 +146,7 @@ static enum png_chunk_type png_chunk_type(const struct png_chunk *chunk)
{ "IDAT", PNG_CHUNK_IDAT },
{ "IEND", PNG_CHUNK_IEND },
{ "PLTE", PNG_CHUNK_PLTE },
{ "tRNS", PNG_CHUNK_tRNS },
};
for (i = 0; i < ARRAY_SIZE(chunk_map); i++)
@ -324,18 +327,100 @@ static void png_reverse_filter_copy_line_plt(uint32_t *data,
const uint8_t *decoded, unsigned width,
unsigned depth, const uint32_t *palette)
{
unsigned i, bit;
unsigned mask = (1 << depth) - 1;
bit = 0;
for (i = 0; i < width; i++, bit += depth)
switch (depth)
{
unsigned byte = bit >> 3;
unsigned val = decoded[byte] >> (8 - depth - (bit & 7));
val &= mask;
data[i] = palette[val];
case 1:
{
unsigned w = width / 8;
unsigned i;
for (i = 0; i < w; i++, decoded++)
{
*data++ = palette[(*decoded >> 7) & 1];
*data++ = palette[(*decoded >> 6) & 1];
*data++ = palette[(*decoded >> 5) & 1];
*data++ = palette[(*decoded >> 4) & 1];
*data++ = palette[(*decoded >> 3) & 1];
*data++ = palette[(*decoded >> 2) & 1];
*data++ = palette[(*decoded >> 1) & 1];
*data++ = palette[*decoded & 1];
}
switch (width & 7)
{
case 7:
data[6] = palette[(*decoded >> 1) & 1];
case 6:
data[5] = palette[(*decoded >> 2) & 1];
case 5:
data[4] = palette[(*decoded >> 3) & 1];
case 4:
data[3] = palette[(*decoded >> 4) & 1];
case 3:
data[2] = palette[(*decoded >> 5) & 1];
case 2:
data[1] = palette[(*decoded >> 6) & 1];
case 1:
data[0] = palette[(*decoded >> 7) & 1];
break;
}
}
break;
case 2:
{
unsigned w = width / 4;
unsigned i;
for (i = 0; i < w; i++, decoded++)
{
*data++ = palette[(*decoded >> 6) & 3];
*data++ = palette[(*decoded >> 4) & 3];
*data++ = palette[(*decoded >> 2) & 3];
*data++ = palette[*decoded & 3];
}
switch (width & 3)
{
case 3:
data[2] = palette[(*decoded >> 2) & 3];
case 2:
data[1] = palette[(*decoded >> 4) & 3];
case 1:
data[0] = palette[(*decoded >> 6) & 3];
break;
}
}
break;
case 4:
{
unsigned w = width / 2;
unsigned i;
for (i = 0; i < w; i++, decoded++)
{
*data++ = palette[*decoded >> 4];
*data++ = palette[*decoded & 0x0f];
}
if (width & 1)
{
*data = palette[*decoded >> 4];
}
}
break;
case 8:
{
unsigned i;
for (i = 0; i < width; i++, decoded++, data++)
{
*data = palette[*decoded];
}
}
break;
}
}
@ -754,6 +839,18 @@ static bool png_read_plte(uint8_t *buf,
return true;
}
static bool png_read_trns(uint8_t *buf, uint32_t *palette, unsigned entries)
{
unsigned i;
for (i = 0; i < entries; i++, buf++, palette++)
{
*palette = (*palette & 0x00ffffff) | *buf << 24;
}
return true;
}
bool png_realloc_idat(const struct png_chunk *chunk, struct idat_buffer *buf)
{
uint8_t *new_buffer = (uint8_t*)realloc(buf->data, buf->size + chunk->size);
@ -900,7 +997,7 @@ bool rpng_iterate_image(rpng_t *rpng)
{
unsigned entries = chunk.size / 3;
if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat)
if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat || rpng->has_trns)
goto error;
if (chunk.size % 3)
@ -918,6 +1015,26 @@ bool rpng_iterate_image(rpng_t *rpng)
}
break;
case PNG_CHUNK_tRNS:
if (rpng->has_idat)
goto error;
if (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT)
{
/* we should compare with the number of palette entries */
if (chunk.size > 256)
goto error;
buf += 8;
if (!png_read_trns(buf, rpng->palette, chunk.size))
goto error;
}
/* TODO: support colorkey in grayscale and truecolor images */
rpng->has_trns = true;
break;
case PNG_CHUNK_IDAT:
if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte)))
goto error;

View File

@ -367,7 +367,8 @@ end:
free(avg_filtered);
free(paeth_filtered);
stream_backend->stream_free(stream);
if (stream_backend)
stream_backend->stream_free(stream);
return ret;
}

View File

@ -256,6 +256,10 @@ static uint8_t *rtga__tga_load(rtga__context *s, unsigned *x, unsigned *y, int *
int RLE_count = 0;
int RLE_repeating = 0;
int read_next_pixel = 1;
(void)tga_palette_start;
(void)tga_x_origin;
(void)tga_y_origin;
/* do a tiny bit of precessing */
if ( tga_image_type >= 8 )
@ -417,9 +421,6 @@ static uint8_t *rtga__tga_load(rtga__context *s, unsigned *x, unsigned *y, int *
if (req_comp && req_comp != tga_comp)
tga_data = rtga__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
tga_palette_start = tga_palette_len = tga_palette_bits =
tga_x_origin = tga_y_origin = 0;
return tga_data;
}

View File

@ -38,6 +38,7 @@ typedef struct RFILE RFILE;
enum
{
RFILE_MODE_READ = 0,
RFILE_MODE_READ_TEXT,
RFILE_MODE_WRITE,
RFILE_MODE_READ_WRITE,
@ -62,6 +63,14 @@ int filestream_close(RFILE *stream);
int filestream_read_file(const char *path, void **buf, ssize_t *len);
char *filestream_gets(RFILE *stream, char *s, size_t len);
char *filestream_getline(RFILE *stream);
int filestream_getc(RFILE *stream);
int filestream_eof(RFILE *stream);
bool filestream_write_file(const char *path, const void *data, ssize_t size);
int filestream_putc(RFILE *stream, int c);

View File

@ -89,7 +89,7 @@ bool file_list_prepend(file_list_t *list,
free(copy);
}
memset(&list->list[0], 0, sizeof(file_list_t));
memset(&list->list[0], 0, sizeof(*list->list) * list->capacity);
list->list[0].label = NULL;
list->list[0].path = NULL;

View File

@ -215,42 +215,45 @@ static bool retro_task_regular_find(retro_task_finder_t func, void *user_data)
static void retro_task_regular_retrieve(task_retriever_data_t *data)
{
retro_task_t *task;
task_retriever_info_t *info;
retro_task_t *task = NULL;
task_retriever_info_t *tail = NULL;
/* Parse all running tasks and handle matching handlers */
for (task = tasks_running.front; task != NULL; task = task->next)
if (task->handler == data->handler)
{
task_retriever_info_t *info = NULL;
if (task->handler != data->handler)
continue;
/* Create new link */
info = (task_retriever_info_t*)malloc(sizeof(task_retriever_info_t));
info->data = malloc(data->element_size);
info->next = NULL;
/* Call retriever function and fill info-specific data */
if (!data->func(task, info->data))
{
/* Create new link */
info = (task_retriever_info_t*)malloc(sizeof(task_retriever_info_t));
info->data = malloc(data->element_size);
info->next = NULL;
/* Call retriever function and fill info-specific data */
if (!data->func(task, info->data))
{
free(info->data);
free(info);
continue;
}
/* Add link to list */
if (data->list == NULL)
{
data->list = info;
tail = data->list;
}
else
{
if (tail)
{
tail->next = info;
tail = tail->next;
}
}
free(info->data);
free(info);
continue;
}
/* Add link to list */
if (data->list)
{
if (tail)
{
tail->next = info;
tail = tail->next;
}
free(info);
}
else
{
data->list = info;
tail = data->list;
}
}
}
static struct retro_task_impl impl_regular = {

View File

@ -129,6 +129,19 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
switch (mode & 0xff)
{
case RFILE_MODE_READ_TEXT:
#if defined(VITA) || defined(PSP)
mode_int = 0777;
flags = PSP_O_RDONLY;
#else
#if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
mode_str = "r";
#endif
/* No "else" here */
flags = O_RDONLY;
#endif
break;
case RFILE_MODE_READ:
#if defined(VITA) || defined(PSP)
mode_int = 0777;
@ -230,6 +243,63 @@ error:
return NULL;
}
char *filestream_getline(RFILE *stream)
{
char* newline = (char*)malloc(9);
char* newline_tmp = NULL;
size_t cur_size = 8;
size_t idx = 0;
int in = filestream_getc(stream);
if (!newline)
return NULL;
while (in != EOF && in != '\n')
{
if (idx == cur_size)
{
cur_size *= 2;
newline_tmp = (char*)realloc(newline, cur_size + 1);
if (!newline_tmp)
{
free(newline);
return NULL;
}
newline = newline_tmp;
}
newline[idx++] = in;
in = filestream_getc(stream);
}
newline[idx] = '\0';
return newline;
}
char *filestream_gets(RFILE *stream, char *s, size_t len)
{
if (!stream)
return NULL;
#if defined(HAVE_BUFFERED_IO)
return fgets(s, len, stream->fp);
#else
return gets(s);
#endif
}
int filestream_getc(RFILE *stream)
{
if (!stream)
return 0;
#if defined(HAVE_BUFFERED_IO)
return fgetc(stream->fp);
#else
return getc(stream->fp);
#endif
}
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
{
if (!stream)
@ -291,6 +361,18 @@ error:
return -1;
}
int filestream_eof(RFILE *stream)
{
ssize_t current_position = filestream_tell(stream);
ssize_t end_position = filestream_seek(stream, 0, SEEK_END);
filestream_seek(stream, current_position, SEEK_SET);
if (current_position >= end_position)
return 1;
return 0;
}
ssize_t filestream_tell(RFILE *stream)
{
if (!stream)

View File

@ -198,8 +198,7 @@ char *intfstream_gets(intfstream_internal_t *intf,
switch (intf->type)
{
case INTFSTREAM_FILE:
/* unimplemented */
break;
return filestream_gets(intf->file.fp, buffer, len);
case INTFSTREAM_MEMORY:
return memstream_gets(intf->memory.fp, buffer, len);
}
@ -215,8 +214,7 @@ int intfstream_getc(intfstream_internal_t *intf)
switch (intf->type)
{
case INTFSTREAM_FILE:
/* unimplemented */
break;
return filestream_getc(intf->file.fp);
case INTFSTREAM_MEMORY:
return memstream_getc(intf->memory.fp);
}