Fix issue 377: getbackuppixel doesn't work after image resize

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1611 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2010-09-12 17:15:16 +00:00
parent c53c6415c3
commit 499c9bc943
6 changed files with 177 additions and 50 deletions

View File

@ -247,12 +247,23 @@ int L_SetPictureSize(lua_State* L)
int w;
int h;
int nb_args=lua_gettop(L);
int i;
LUA_ARG_LIMIT (2, "setpicturesize");
LUA_ARG_NUMBER(1, "setpicturesize", w, 1, 9999);
LUA_ARG_NUMBER(2, "setpicturesize", h, 1, 9999);
Resize_image(w, h); // TODO: a return value to catch runtime errors
Backup_in_place(w, h);
// part of Resize_image() : the pixel copy part.
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Copy_part_of_image_to_another(
Main_backups->Pages->Next->Image[i],0,0,Min(Main_backups->Pages->Next->Width,Main_image_width),
Min(Main_backups->Pages->Next->Height,Main_image_height),Main_backups->Pages->Next->Width,
Main_backups->Pages->Image[i],0,0,Main_image_width);
}
Redraw_layered_image();
return 0;
}

View File

@ -617,7 +617,8 @@ void Resize_image(word chosen_width,word chosen_height)
// |B| | C = Nouvelle image
// +-+-+
if (Backup_with_new_dimensions(1,Main_backups->Pages->Nb_layers,chosen_width,chosen_height))
Upload_infos_page_main(Main_backups->Pages);
if (Backup_with_new_dimensions(chosen_width,chosen_height))
{
// La nouvelle page a pu être allouée, elle est pour l'instant pleine de
// 0s. Elle fait Main_image_width de large.

View File

@ -405,7 +405,7 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
// Other loading
case CONTEXT_MAIN_IMAGE:
if (Backup_with_new_dimensions(0,1,width,height))
if (Backup_new_image(1,width,height))
{
// La nouvelle page a pu être allouée, elle est pour l'instant pleine
// de 0s. Elle fait Main_image_width de large.

View File

@ -811,19 +811,10 @@ void Set_number_of_backups(int nb_backups)
// (nb_backups = Nombre de backups, sans compter les pages courantes)
}
int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
int Backup_new_image(byte layers,int width,int height)
{
// Retourne 1 si une nouvelle page est disponible (alors pleine de 0) et
// 0 sinon.
// Retourne 1 si une nouvelle page est disponible et 0 sinon
T_Page * new_page;
int return_code=0;
int i;
if (upload)
// On remet à jour l'état des infos de la page courante (pour pouvoir les
// retrouver plus tard)
Upload_infos_page_main(Main_backups->Pages);
// On crée un descripteur pour la nouvelle page courante
new_page=New_page(layers);
@ -832,21 +823,60 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
Error(0);
return 0;
}
Upload_infos_page_main(new_page);
// Other data not covered by Upload_infos_page_main.
// I dunno really why we don't use Copy_S_Page
strcpy(new_page->Filename, Main_backups->Pages->Filename);
strcpy(new_page->File_directory, Main_backups->Pages->File_directory);
new_page->Gradients=Dup_gradient(upload?Main_backups->Pages:NULL);
new_page->Background_transparent=Main_backups->Pages->Background_transparent;
new_page->Transparent_color=Main_backups->Pages->Transparent_color;
//
new_page->Width=width;
new_page->Height=height;
if (Create_new_page(new_page,Main_backups,0xFFFFFFFF))
new_page->Transparent_color=0;
new_page->Gradients=Dup_gradient(NULL);
if (!Create_new_page(new_page,Main_backups,0xFFFFFFFF))
{
for (i=0; i<layers;i++)
Error(0);
return 0;
}
Update_buffers(width, height);
Download_infos_page_main(Main_backups->Pages);
return 1;
}
int Backup_with_new_dimensions(int width,int height)
{
// Retourne 1 si une nouvelle page est disponible (alors pleine de 0) et
// 0 sinon.
T_Page * new_page;
int i;
// On crée un descripteur pour la nouvelle page courante
new_page=New_page(Main_backups->Pages->Nb_layers);
if (!new_page)
{
Error(0);
return 0;
}
new_page->Width=width;
new_page->Height=height;
new_page->Transparent_color=0;
if (!Create_new_page(new_page,Main_backups,0xFFFFFFFF))
{
Error(0);
return 0;
}
// Copy data from previous history step
memcpy(Main_backups->Pages->Palette,Main_backups->Pages->Next->Palette,sizeof(T_Palette));
strcpy(Main_backups->Pages->Comment,Main_backups->Pages->Next->Comment);
Main_backups->Pages->File_format=Main_backups->Pages->Next->File_format;
strcpy(Main_backups->Pages->Filename, Main_backups->Pages->Next->Filename);
strcpy(Main_backups->Pages->File_directory, Main_backups->Pages->Next->File_directory);
Main_backups->Pages->Gradients=Dup_gradient(Main_backups->Pages->Next);
Main_backups->Pages->Background_transparent=Main_backups->Pages->Next->Background_transparent;
Main_backups->Pages->Transparent_color=Main_backups->Pages->Next->Transparent_color;
// Fill with transparent color
for (i=0; i<Main_backups->Pages->Nb_layers;i++)
{
memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
}
@ -855,7 +885,8 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
Download_infos_page_main(Main_backups->Pages);
// Same code as in End_of_modification():
// Same code as in End_of_modification(),
// Without saving a safety backup:
#ifndef NOLAYERS
memcpy(Main_visible_image_backup.Image,
Main_visible_image.Image,
@ -866,9 +897,87 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
Update_FX_feedback(Config.FX_Feedback);
// --
return_code=1;
return 1;
}
///
/// Resizes a backup step in-place.
/// Should only be called after an actual backup, because it loses the current.
/// pixels. This function is meant to be used from within Lua scripts.
int Backup_in_place(int width,int height)
{
// Retourne 1 si une nouvelle page est disponible (alors pleine de 0) et
// 0 sinon.
int i;
byte ** new_layer;
// Perform all allocations first
new_layer=calloc(Main_backups->Pages->Nb_layers,1);
if (!new_layer)
return 0;
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
new_layer[i]=New_layer(height*width);
if (!new_layer[i])
{
// Allocation error
for (; i>0; i--)
free(new_layer[i]);
free(new_layer);
return 0;
}
return return_code;
}
// Now ok to proceed
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
// Replace layers
Free_layer(Main_backups->Pages,i);
Main_backups->Pages->Image[i]=new_layer[i];
// Fill with transparency
memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
}
Main_backups->Pages->Width=width;
Main_backups->Pages->Height=height;
Download_infos_page_main(Main_backups->Pages);
// The following is part of Update_buffers()
// (without changing the backup buffer)
#ifndef NOLAYERS
// At least one dimension is different
if (Main_visible_image.Width*Main_visible_image.Height != width*height)
{
// Current image
free(Main_visible_image.Image);
Main_visible_image.Image = (byte *)malloc(width * height);
if (Main_visible_image.Image == NULL)
return 0;
}
Main_visible_image.Width = width;
Main_visible_image.Height = height;
if (Main_visible_image_depth_buffer.Width*Main_visible_image_depth_buffer.Height != width*height)
{
// Depth buffer
free(Main_visible_image_depth_buffer.Image);
Main_visible_image_depth_buffer.Image = (byte *)malloc(width * height);
if (Main_visible_image_depth_buffer.Image == NULL)
return 0;
}
Main_visible_image_depth_buffer.Width = width;
Main_visible_image_depth_buffer.Height = height;
#endif
Update_screen_targets();
return 1;
}
int Backup_and_resize_the_spare(int width,int height)
@ -1121,6 +1230,11 @@ void End_of_modification(void)
//Update_buffers(Main_image_width, Main_image_height);
#ifndef NOLAYERS
// Backup buffer can have "wrong" size if a Lua script
// performs a resize.
Update_buffers(Main_image_width, Main_image_height);
//
memcpy(Main_visible_image_backup.Image,
Main_visible_image.Image,
Main_image_width*Main_image_height);

View File

@ -93,7 +93,7 @@ void Free_page_of_a_list(T_List_of_pages * list);
int Init_all_backup_lists(int width,int height);
void Set_number_of_backups(int nb_backups);
int Backup_with_new_dimensions(int upload,byte layers,int width,int height);
int Backup_with_new_dimensions(int width,int height);
/// Backup the spare image, the one you don't see.
void Backup_the_spare(dword layer_mask);
int Backup_and_resize_the_spare(int width,int height);

View File

@ -369,8 +369,9 @@ void Button_Transform_menu(void)
old_width=Main_image_width;
old_height=Main_image_height;
Upload_infos_page_main(Main_backups->Pages);
// Allocate a new page
if (Backup_with_new_dimensions(1,Main_backups->Pages->Nb_layers,new_width,new_height))
if (Backup_with_new_dimensions(new_width,new_height))
{
// The new image is allocated, the new dimensions are already updated.