Added MCS file inserting, used it in CAS decoding.
This commit is contained in:
parent
4913619f7d
commit
139a0aade0
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
193
src/manage/mcs.c
193
src/manage/mcs.c
|
@ -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);
|
||||
}
|
||||
|
|
Reference in New Issue