cake
/
libg1m
Archived
1
0
Fork 0

Added MCS file inserting, used it in CAS decoding.

This commit is contained in:
Thomas Touhey 2017-03-16 11:59:37 +01:00
parent 4913619f7d
commit 139a0aade0
3 changed files with 59 additions and 172 deletions

View File

@ -129,13 +129,9 @@ extern int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer);
/* ************************************************************************** */
/* MCS archive management */
/* ************************************************************************** */
/* add MCS files */
extern int g1m_putmcs_program(g1m_t *handle, g1m_mcsfile_t **pfile,
char *name, char *password, char *content);
extern int g1m_putmcs_capture(g1m_t *handle, g1m_mcsfile_t **pfile,
int id, int width, int height, uint32_t **pixels);
extern int g1m_putmcs_picture(g1m_t *handle, g1m_mcsfile_t **pfile,
int id, uint32_t **pixels_one, uint32_t **pixels_two);
/* create and insert an MCS file into a MCS archive */
extern int g1m_mcs_insert(g1m_t *handle, const g1m_mcshead_t *head,
g1m_mcsfile_t **tofile);
# ifdef __cplusplus
}

View File

@ -275,37 +275,13 @@ int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer)
err = g1m_decode_casfiles_part(&head, heads, buffer);
if (err) goto fail;
}
} else
heads[0] = head;
/* prepare space in the index */
int required_size = handle->count
+ (head.flags & g1m_mcsflag_multiple) ? head.count : 1;
if (required_size > handle->_size) {
int newsize = required_size + 2;
log_info("index not big enough, allocating from %d to %d slots",
handle->_size, newsize);
/* allocate new index */
err = g1m_error_alloc;
g1m_mcsfile_t **index = calloc(sizeof(g1m_mcsfile_t*), newsize);
if (!index) goto fail;
/* copy old data */
memcpy(index, handle->files,
sizeof(g1m_mcsfile_t*) * handle->_size);
memset(&index[handle->_size], 0,
sizeof(g1m_mcsfile_t*) * (newsize - handle->_size));
handle->files = index;
handle->_size = newsize;
}
} else heads[0] = head;
for (int i = 0; i < numheads; i++) {
/* prepare the file */
log_info("Preparing the group file #%d", i);
err = g1m_make_mcsfile(&handle->files[handle->count], &heads[i]);
g1m_mcsfile_t *file; err = g1m_mcs_insert(handle, &heads[i], &file);
if (err) goto fail;
g1m_mcsfile_t *file = handle->files[handle->count]; handle->count++;
/* read each part */
#if LOGLEVEL <= ll_info

View File

@ -20,20 +20,22 @@
#define MCS_CHUNK_SIZE 16
/* ************************************************************************** */
/* Internal functions */
/* General function for inserting files */
/* ************************************************************************** */
/**
* find_space_for_file:
* Find space for some element function.
* g1m_mcs_insert:
* Find space for a file and allocate.
*
* @arg handle the handle.
* @arg head the head.
* @arg tofile the file pointer for the user.
* @return the mcs file (NULL if allocation error).
*/
static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head)
int g1m_mcs_insert(g1m_t *handle, const g1m_mcshead_t *head,
g1m_mcsfile_t **tofile)
{
g1m_mcsfile_t **pfile = NULL;
g1m_mcsfile_t **pfile = NULL; *tofile = NULL;
/* look if this file isn't already in the tab */
int istyp = g1m_mcshead_uses_id(head);
@ -44,21 +46,57 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head)
continue;
}
if ((file->head.type == head->type) && (istyp ?
file->head.id == head->id : !strcmp(file->head.name, head->name))) {
g1m_free_mcsfile(file);
pfile = &handle->files[i];
goto found;
/* loop assertions */
if (file->head.type != head->type)
continue;
if (head->type) {
if (istyp) {
if (head->id != file->head.id)
continue;
} else if (strcmp(file->head.name, head->name))
continue;
} else switch (g1m_mcsinfo(head)) {
case g1m_mcsinfo_mcs:
if (strncmp((char*)head->_group, (char*)file->head._group, 16))
continue;
if (strncmp((char*)head->_dirname, (char*)file->head._dirname, 8))
continue;
if (strncmp((char*)head->name, (char*)file->head.name, 8))
continue;
break;
case g1m_mcsinfo_cas:
case g1m_mcsinfo_caspro:
if (strncmp((char*)head->_datatype,
(char*)file->head._datatype, 2))
continue;
break;
default: continue;
}
/* slot was found! */
g1m_free_mcsfile(file);
pfile = &handle->files[i];
goto found;
}
/* if no empty space was found, take one at the end (allocate if needed) */
if (!pfile) {
if (handle->count >= handle->_size) {
handle->_size = handle->count + MCS_CHUNK_SIZE;
handle->files = realloc(handle->files,
handle->_size * sizeof(g1m_mcsfile_t**));
if (!handle->files) return (NULL);
/* allocate new index */
int newsize = handle->count + MCS_CHUNK_SIZE;
g1m_mcsfile_t **newindex = malloc(newsize * sizeof(g1m_mcsfile_t*));
if (!newindex) return (g1m_error_alloc);
/* copy the data from the old index */
memcpy(newindex, handle->files,
handle->_size * sizeof(g1m_mcsfile_t*));
memset(&newindex[handle->_size], 0,
(newsize - handle->_size) * sizeof(g1m_mcsfile_t*));
/* free old, assign new */
free(handle->files);
handle->files = newindex;
handle->_size = newsize;
}
pfile = &handle->files[handle->count++];
}
@ -66,132 +104,9 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head)
found:;
/* make the file */
int err = g1m_make_mcsfile(pfile, head);
if (err) return (NULL);
if (err) return (err);
/* return it */
return (*pfile);
}
/* ************************************************************************** */
/* Create files in archive */
/* ************************************************************************** */
/**
* g1m_putmcs_program:
* Put a program in a MCS handle.
*
* @arg handle the handle.
* @arg pfile pointer to the file pointer to set.
* @arg name the name of the program.
* @arg password the password (NULL if none).
* @return the error code (0 if ok).
*/
int g1m_putmcs_program(g1m_t *handle, g1m_mcsfile_t **pfile,
char *name, char *password, char *content)
{
/* check if the operation is supported */
if (~handle->type & g1m_type_mcs) return (g1m_error_op);
/* find the file */
g1m_mcshead_t head = {
.type = g1m_mcstype_program,
.size = strlen(content)
};
strncpy(head.name, name, 8); head.name[8] = 0;
if (password) strncpy(head.password, password, 8);
else head.password[0] = 0;
g1m_mcsfile_t *file = find_space_for_file(handle, &head);
if (!file) return (g1m_error_alloc);
/* set content */
memcpy(file->content, content, file->head.size);
/* no error */
if (pfile) *pfile = file;
return (0);
}
/**
* g1m_putmcs_capture:
* Put a capture in an MCS handle.
*
* @arg handle the handle.
* @arg pfile the file pointer to get file.
* @arg id the capture ID (1 to 20).
* @arg width the capture width.
* @arg height the capture height.
* @arg pic the pixels to copy.
* @return the error code (0 if ok).
*/
int g1m_putmcs_capture(g1m_t *handle, g1m_mcsfile_t **pfile,
int id, int width, int height, uint32_t **pic)
{
/* check if the operation is supported */
if (~handle->type & g1m_type_mcs || id < 1 || id > 20)
return (g1m_error_op);
/* find the file */
g1m_mcshead_t head = {
.type = g1m_mcstype_capture, .id = id,
.width = width, .height = height
};
g1m_mcsfile_t *file = find_space_for_file(handle, &head);
if (!file) return (g1m_error_alloc);
/* copy pixels */
uint32_t *pix = &file->pic[0][0];
for (int y = 0; y < height; y++) {
uint32_t *line = *pic++;
for (int x = 0; x < width; x++)
*pix++ = *line++;
}
/* no error */
if (pfile) *pfile = file;
return (0);
}
/**
* g1m_putmcs_picture:
* Put a picture in an MCS handle.
*
* @arg handle the handle.
* @arg pfile the file pointer to get.
* @arg id the picture ID (1 to 20).
* @arg pic_one pixels of the first 128x64 image to copy.
* @arg pic_two pixels of the second 128x64 image to copy.
* @return the error code (0 if ok).
*/
int g1m_putmcs_picture(g1m_t *handle, g1m_mcsfile_t **pfile,
int id, uint32_t **pic_one, uint32_t **pic_two)
{
/* check if the operation is supported */
if (~handle->type & g1m_type_mcs || id < 1 || id > 20)
return (g1m_error_op);
/* find the file */
g1m_mcshead_t head = {
.type = g1m_mcstype_picture, .id = id,
.width = 128, .height = 64
};
g1m_mcsfile_t *file = find_space_for_file(handle, &head);
if (!file) return (g1m_error_alloc);
/* copy pixels */
uint32_t *one = &file->pics[0][0][0];
uint32_t *two = &file->pics[1][0][0];
for (int y = 0; y < 64; y++) {
uint32_t *line_one = *pic_one++;
uint32_t *line_two = *pic_two++;
for (int x = 0; x < 128; x++) {
*one++ = *line_one++;
*two++ = *line_two++;
}
}
/* no error */
if (pfile) *pfile = file;
*tofile = *pfile;
return (0);
}