Implemented back the Mask mode. Fixed a historical bug of memory violation if you used Mask with images of different sizes (would crash all platforms except DOS)

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1237 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2009-12-07 20:39:32 +00:00
parent 141a523c46
commit cf54bb5f29
9 changed files with 126 additions and 90 deletions

View File

@ -1192,6 +1192,9 @@ void Button_Page(void)
Exchange_main_and_spare(); Exchange_main_and_spare();
// On fait le reste du travail "à la main": // On fait le reste du travail "à la main":
SWAP_PBYTES(Main_visible_image.Image,Spare_visible_image.Image)
SWAP_WORDS (Main_visible_image.Width,Spare_visible_image.Width)
SWAP_WORDS (Main_visible_image.Height,Spare_visible_image.Height)
SWAP_SHORTS(Main_offset_X,Spare_offset_X) SWAP_SHORTS(Main_offset_X,Spare_offset_X)
SWAP_SHORTS(Main_offset_Y,Spare_offset_Y) SWAP_SHORTS(Main_offset_Y,Spare_offset_Y)
SWAP_SHORTS(Old_main_offset_X,Old_spare_offset_X) SWAP_SHORTS(Old_main_offset_X,Old_spare_offset_X)
@ -1223,8 +1226,13 @@ void Button_Page(void)
SWAP_BYTES (Main_current_layer,Spare_current_layer) SWAP_BYTES (Main_current_layer,Spare_current_layer)
SWAP_DWORDS(Main_layers_visible,Spare_layers_visible) SWAP_DWORDS(Main_layers_visible,Spare_layers_visible)
//Redraw_layered_image();
// replaced by
Update_buffers(Main_image_width, Main_image_height);
Update_depth_buffer();
Update_screen_targets(); Update_screen_targets();
Redraw_layered_image(); End_of_modification();
// --
// A la fin, on affiche l'écran // A la fin, on affiche l'écran
for (factor_index=0; ZOOM_FACTOR[factor_index]!=Main_magnifier_factor; factor_index++); for (factor_index=0; ZOOM_FACTOR[factor_index]!=Main_magnifier_factor; factor_index++);

View File

@ -2882,7 +2882,7 @@ byte Read_pixel_from_current_screen (word x,word y)
if (color != Main_backups->Pages->Transparent_color) // transparent color if (color != Main_backups->Pages->Transparent_color) // transparent color
return color; return color;
depth = *(Visible_image_depth_buffer.Image+x+y*Main_image_width); depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
return *(Main_backups->Pages->Image[depth] + x+y*Main_image_width); return *(Main_backups->Pages->Image[depth] + x+y*Main_image_width);
#else #else
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer]); return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer]);
@ -2892,7 +2892,7 @@ byte Read_pixel_from_current_screen (word x,word y)
void Pixel_in_current_screen (word x,word y,byte color,int with_preview) void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
{ {
#ifndef NOLAYERS #ifndef NOLAYERS
byte depth = *(Visible_image_depth_buffer.Image+x+y*Main_image_width); byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color; *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
if ( depth <= Main_current_layer) if ( depth <= Main_current_layer)
{ {

View File

@ -107,8 +107,6 @@ void Pixel_load_in_24b_preview(short x_pos,short y_pos,byte r,byte g,byte b);
// //
extern enum PIXEL_RATIO Ratio_of_loaded_image;
void Set_file_error(int value); void Set_file_error(int value);
void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio); void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio);

12
main.c
View File

@ -699,18 +699,6 @@ int Init_program(int argc,char * argv[])
Spare_image_width=Screen_width/Pixel_width; Spare_image_width=Screen_width/Pixel_width;
Spare_image_height=Screen_height/Pixel_height; Spare_image_height=Screen_height/Pixel_height;
#ifndef NOLAYERS
Visible_image[0].Width = 0;
Visible_image[0].Height = 0;
Visible_image[0].Image = NULL;
Visible_image[1].Width = 0;
Visible_image[1].Height = 0;
Visible_image[1].Image = NULL;
Visible_image_depth_buffer.Width = 0;
Visible_image_depth_buffer.Height = 0;
Visible_image_depth_buffer.Image = NULL;
#endif
// Allocation de mémoire pour les différents écrans virtuels (et brosse) // Allocation de mémoire pour les différents écrans virtuels (et brosse)
if (Init_all_backup_lists(Screen_width,Screen_height)==0) if (Init_all_backup_lists(Screen_width,Screen_height)==0)
Error(ERROR_MEMORY); Error(ERROR_MEMORY);

17
misc.c
View File

@ -37,6 +37,7 @@
#include "palette.h" #include "palette.h"
#include "input.h" #include "input.h"
#include "graph.h" #include "graph.h"
#include "pages.h"
///Count used palette indexes in the whole picture ///Count used palette indexes in the whole picture
///Return the total number of different colors ///Return the total number of different colors
@ -287,10 +288,18 @@ void Copy_part_of_image_to_another(byte * source,word source_x,word source_y,wor
byte Read_pixel_from_spare_screen(word x,word y) byte Read_pixel_from_spare_screen(word x,word y)
{ {
return 0; // return *(Spare_screen+y*Spare_image_width+x);
/* Temporarily disabled. Need to implement a third Visible_image buffer
return *(Spare_screen+y*Spare_image_width+x); // Clipping is required as this can be called with coordinates from main image
*/ // (can be a bigger or smaller image)
if (x>=Spare_image_width || y>=Spare_image_height)
return 0; // TODO: we could return the spare's transparent color, if it has one.
#ifndef NOLAYERS
return *(Spare_visible_image.Image + y*Spare_image_width + x);
#else
return *(Spare_backups->Pages->Image[Spare_current_layer] + y*Spare_image_width + x);
#endif
} }
void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height) void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height)

1
misc.h
View File

@ -30,6 +30,7 @@
#define SWAP_DWORDS(a,b) { dword c=a; a=b; b=c;} #define SWAP_DWORDS(a,b) { dword c=a; a=b; b=c;}
#define SWAP_SHORTS(a,b) { short c=a; a=b; b=c;} #define SWAP_SHORTS(a,b) { short c=a; a=b; b=c;}
#define SWAP_FLOATS(a,b) { float c=a; a=b; b=c;} #define SWAP_FLOATS(a,b) { float c=a; a=b; b=c;}
#define SWAP_PBYTES(a,b) { byte * c=a; a=b; b=c;}
void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width); void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width);
void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width); void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width);

157
pages.c
View File

@ -37,11 +37,12 @@
/// Array of two images, that contains the "flattened" version of the visible layers. /// Array of two images, that contains the "flattened" version of the visible layers.
#ifndef NOLAYERS #ifndef NOLAYERS
T_Image Visible_image[2]; T_Bitmap Main_visible_image;
T_Image Visible_image_depth_buffer; T_Bitmap Main_visible_image_backup;
T_Bitmap Main_visible_image_depth_buffer;
T_Bitmap Spare_visible_image;
#endif #endif
/// ///
/// GESTION DES PAGES /// GESTION DES PAGES
/// ///
@ -182,13 +183,13 @@ void Redraw_layered_image(void)
{ {
if ((1<<layer) & Main_layers_visible) if ((1<<layer) & Main_layers_visible)
{ {
// Copy it in Visible_image[0] // Copy it in Main_visible_image
memcpy(Visible_image[0].Image, memcpy(Main_visible_image.Image,
Main_backups->Pages->Image[layer], Main_backups->Pages->Image[layer],
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
// Initialize the depth buffer // Initialize the depth buffer
memset(Visible_image_depth_buffer.Image, memset(Main_visible_image_depth_buffer.Image,
layer, layer,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
@ -208,9 +209,9 @@ void Redraw_layered_image(void)
byte color = *(Main_backups->Pages->Image[layer]+i); byte color = *(Main_backups->Pages->Image[layer]+i);
if (color != Main_backups->Pages->Transparent_color) // transparent color if (color != Main_backups->Pages->Transparent_color) // transparent color
{ {
*(Visible_image[0].Image+i) = color; *(Main_visible_image.Image+i) = color;
if (layer != Main_current_layer) if (layer != Main_current_layer)
*(Visible_image_depth_buffer.Image+i) = layer; *(Main_visible_image_depth_buffer.Image+i) = layer;
} }
} }
} }
@ -235,7 +236,7 @@ void Update_depth_buffer(void)
if ((1<<layer) & Main_layers_visible) if ((1<<layer) & Main_layers_visible)
{ {
// Initialize the depth buffer // Initialize the depth buffer
memset(Visible_image_depth_buffer.Image, memset(Main_visible_image_depth_buffer.Image,
layer, layer,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
@ -259,7 +260,7 @@ void Update_depth_buffer(void)
byte color = *(Main_backups->Pages->Image[layer]+i); byte color = *(Main_backups->Pages->Image[layer]+i);
if (color != Main_backups->Pages->Transparent_color) // transparent color if (color != Main_backups->Pages->Transparent_color) // transparent color
{ {
*(Visible_image_depth_buffer.Image+i) = layer; *(Main_visible_image_depth_buffer.Image+i) = layer;
} }
} }
} }
@ -274,17 +275,17 @@ void Redraw_current_layer(void)
int i; int i;
for (i=0; i<Main_image_width*Main_image_height; i++) for (i=0; i<Main_image_width*Main_image_height; i++)
{ {
byte depth = *(Visible_image_depth_buffer.Image+i); byte depth = *(Main_visible_image_depth_buffer.Image+i);
if (depth<=Main_current_layer) if (depth<=Main_current_layer)
{ {
byte color = *(Main_backups->Pages->Image[Main_current_layer]+i); byte color = *(Main_backups->Pages->Image[Main_current_layer]+i);
if (color != Main_backups->Pages->Transparent_color) // transparent color if (color != Main_backups->Pages->Transparent_color) // transparent color
{ {
*(Visible_image[0].Image+i) = color; *(Main_visible_image.Image+i) = color;
} }
else else
{ {
*(Visible_image[0].Image+i) = *(Main_backups->Pages->Image[depth]+i); *(Main_visible_image.Image+i) = *(Main_backups->Pages->Image[depth]+i);
} }
} }
} }
@ -565,31 +566,11 @@ void Free_page_of_a_list(T_List_of_pages * list)
} }
} }
/// Resize one of the special bitmap buffers, if necessary.
int Update_buffer(T_Image * image, int width, int height)
{
// At least one dimension is different
if (image->Width != width || image->Height != height)
{
// Actual size difference
if (image->Width * image->Height != width * height)
{
free(image->Image);
image->Image = (byte *)malloc(width * height);
if (image->Image == NULL)
return 0;
}
image->Width = width;
image->Height = height;
}
return 1;
}
void Update_screen_targets(void) void Update_screen_targets(void)
{ {
#ifndef NOLAYERS #ifndef NOLAYERS
Main_screen=Visible_image[0].Image; Main_screen=Main_visible_image.Image;
Screen_backup=Visible_image[1].Image; Screen_backup=Main_visible_image_backup.Image;
#else #else
Main_screen=Main_backups->Pages->Image[Main_current_layer]; Main_screen=Main_backups->Pages->Image[Main_current_layer];
Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer]; Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer];
@ -600,16 +581,63 @@ void Update_screen_targets(void)
int Update_buffers(int width, int height) int Update_buffers(int width, int height)
{ {
#ifndef NOLAYERS #ifndef NOLAYERS
if (! Update_buffer(&Visible_image_depth_buffer, width, height)) // At least one dimension is different
return 0; if (Main_visible_image.Width*Main_visible_image.Height != width*height)
if (! Update_buffer(&Visible_image[0], width, height)) {
return 0; // Current image
if (! Update_buffer(&Visible_image[1], width, height)) free(Main_visible_image.Image);
return 0; 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_backup.Width*Main_visible_image_backup.Height != width*height)
{
// Previous image
free(Main_visible_image_backup.Image);
Main_visible_image_backup.Image = (byte *)malloc(width * height);
if (Main_visible_image_backup.Image == NULL)
return 0;
}
Main_visible_image_backup.Width = width;
Main_visible_image_backup.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 #endif
Update_screen_targets(); Update_screen_targets();
return 1; return 1;
} }
/// Update all the special image buffers of the spare page, if necessary.
int Update_spare_buffers(int width, int height)
{
#ifndef NOLAYERS
// At least one dimension is different
if (Spare_visible_image.Width*Spare_visible_image.Height != width*height)
{
// Current image
free(Spare_visible_image.Image);
Spare_visible_image.Image = (byte *)malloc(width * height);
if (Spare_visible_image.Image == NULL)
return 0;
}
Spare_visible_image.Width = width;
Spare_visible_image.Height = height;
#endif
return 1;
}
/// ///
/// GESTION DES BACKUPS /// GESTION DES BACKUPS
@ -639,25 +667,28 @@ int Init_all_backup_lists(int width,int height)
memset(Main_backups->Pages->Image[i], 0, width*height); memset(Main_backups->Pages->Image[i], 0, width*height);
} }
#ifndef NOLAYERS #ifndef NOLAYERS
Visible_image[0].Width = 0; Main_visible_image.Width = 0;
Visible_image[0].Height = 0; Main_visible_image.Height = 0;
Visible_image[0].Image = NULL; Main_visible_image.Image = NULL;
Main_visible_image_backup.Image = NULL;
Main_visible_image_depth_buffer.Image = NULL;
Spare_visible_image.Width = 0;
Spare_visible_image.Height = 0;
Spare_visible_image.Image = NULL;
Visible_image[1].Width = 0;
Visible_image[1].Height = 0;
Visible_image[1].Image = NULL;
Visible_image_depth_buffer.Width = 0;
Visible_image_depth_buffer.Height = 0;
Visible_image_depth_buffer.Image = NULL;
#endif #endif
if (!Update_buffers(width, height)) if (!Update_buffers(width, height))
return 0; return 0;
if (!Update_spare_buffers(width, height))
return 0;
#ifndef NOLAYERS #ifndef NOLAYERS
// For speed, instead of Redraw_layered_image() we'll directly set the buffers. // For speed, instead of Redraw_layered_image() we'll directly set the buffers.
memset(Visible_image[0].Image, 0, width*height); memset(Main_visible_image.Image, 0, width*height);
memset(Visible_image[1].Image, 0, width*height); memset(Main_visible_image_backup.Image, 0, width*height);
memset(Visible_image_depth_buffer.Image, 0, width*height); memset(Main_visible_image_depth_buffer.Image, 0, width*height);
memset(Spare_visible_image.Image, 0, width*height);
#endif #endif
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
Download_infos_backup(Main_backups); Download_infos_backup(Main_backups);
@ -735,7 +766,7 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
Update_buffers(width, height); Update_buffers(width, height);
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
Download_infos_backup(Main_backups); End_of_modification();
return_code=1; return_code=1;
} }
@ -864,8 +895,6 @@ void Undo(void)
// On extrait ensuite les infos sur la nouvelle page courante // On extrait ensuite les infos sur la nouvelle page courante
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
// Et celles du backup
Download_infos_backup(Main_backups);
// Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même // Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même
// palette que la page courante. Mais en temps normal, le backup // palette que la page courante. Mais en temps normal, le backup
// n'est pas utilisé à la suite d'un Undo. Donc ça ne devrait pas // n'est pas utilisé à la suite d'un Undo. Donc ça ne devrait pas
@ -873,6 +902,7 @@ void Undo(void)
Check_layers_limits(); Check_layers_limits();
Redraw_layered_image(); Redraw_layered_image();
End_of_modification();
} }
@ -893,8 +923,6 @@ void Redo(void)
// On extrait ensuite les infos sur la nouvelle page courante // On extrait ensuite les infos sur la nouvelle page courante
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
// Et celles du backup
Download_infos_backup(Main_backups);
// Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même // Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même
// palette que la page courante. Mais en temps normal, le backup // palette que la page courante. Mais en temps normal, le backup
// n'est pas utilisé à la suite d'un Redo. Donc ça ne devrait pas // n'est pas utilisé à la suite d'un Redo. Donc ça ne devrait pas
@ -902,6 +930,7 @@ void Redo(void)
Check_layers_limits(); Check_layers_limits();
Redraw_layered_image(); Redraw_layered_image();
End_of_modification();
} }
@ -912,8 +941,6 @@ void Free_current_page(void)
// On extrait ensuite les infos sur la nouvelle page courante // On extrait ensuite les infos sur la nouvelle page courante
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
// Et celles du backup
Download_infos_backup(Main_backups);
// Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même // Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même
// palette que la page courante. Mais en temps normal, le backup // palette que la page courante. Mais en temps normal, le backup
// n'est pas utilisé à la suite d'une destruction de page. Donc ça ne // n'est pas utilisé à la suite d'une destruction de page. Donc ça ne
@ -922,6 +949,7 @@ void Free_current_page(void)
Update_buffers(Main_backups->Pages->Width, Main_backups->Pages->Height); Update_buffers(Main_backups->Pages->Width, Main_backups->Pages->Height);
Check_layers_limits(); Check_layers_limits();
Redraw_layered_image(); Redraw_layered_image();
End_of_modification();
} }
void Exchange_main_and_spare(void) void Exchange_main_and_spare(void)
@ -942,8 +970,6 @@ void Exchange_main_and_spare(void)
// On extrait ensuite les infos sur les nouvelles pages courante, brouillon // On extrait ensuite les infos sur les nouvelles pages courante, brouillon
// et backup. // et backup.
Update_buffers(Main_backups->Pages->Width, Main_backups->Pages->Height);
/* SECTION GROS CACA PROUT PROUT */ /* SECTION GROS CACA PROUT PROUT */
// Auparavant on ruse en mettant déjà à jour les dimensions de la // Auparavant on ruse en mettant déjà à jour les dimensions de la
// nouvelle page courante. Si on ne le fait pas, le "Download" va détecter // nouvelle page courante. Si on ne le fait pas, le "Download" va détecter
@ -954,7 +980,6 @@ void Exchange_main_and_spare(void)
Main_image_height=Main_backups->Pages->Height; Main_image_height=Main_backups->Pages->Height;
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
Download_infos_backup(Main_backups);
Download_infos_page_spare(Spare_backups->Pages); Download_infos_page_spare(Spare_backups->Pages);
} }
@ -964,8 +989,8 @@ void End_of_modification(void)
//Update_buffers(Main_image_width, Main_image_height); //Update_buffers(Main_image_width, Main_image_height);
#ifndef NOLAYERS #ifndef NOLAYERS
memcpy(Visible_image[1].Image, memcpy(Main_visible_image_backup.Image,
Visible_image[0].Image, Main_visible_image.Image,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
#else #else
Update_screen_targets(); Update_screen_targets();

11
pages.h
View File

@ -32,8 +32,15 @@
/////////////////////////// BACKUP /////////////////////////////////////// /////////////////////////// BACKUP ///////////////////////////////////////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
extern T_Image Visible_image[2]; /// The pixels of visible layers, flattened copy.
extern T_Image Visible_image_depth_buffer; extern T_Bitmap Main_visible_image;
/// The pixels of visible layers, flattened copy, used for no-feedback effects.
extern T_Bitmap Main_visible_image_backup;
/// The index of visible pixels from ::Visible image. Points to the right layer.
extern T_Bitmap Main_visible_image_depth_buffer;
/// The pixels of visible layers for the spare page, flattened copy.
extern T_Bitmap Spare_visible_image;
/// ///
/// INDIVIDUAL PAGES /// INDIVIDUAL PAGES

View File

@ -366,7 +366,7 @@ typedef struct
int Width; ///< Image width in pixels. int Width; ///< Image width in pixels.
int Height; ///< Image height in pixels. int Height; ///< Image height in pixels.
byte * Image; ///< Pixel data for the image. byte * Image; ///< Pixel data for the image.
} T_Image; } T_Bitmap;
/// A single memorized brush from the Brush Container /// A single memorized brush from the Brush Container
typedef struct typedef struct