move some functions from loadsave.c to loadsavefuncs.c
This commit is contained in:
		
							parent
							
								
									90e5a61d0f
								
							
						
					
					
						commit
						d5953ad51a
					
				@ -795,13 +795,14 @@ endif
 | 
			
		||||
 | 
			
		||||
# This is the list of the objects we want to build. Dependancies are built by "make depend" automatically.
 | 
			
		||||
OBJS = main.o init.o graph.o $(APIOBJ) misc.o special.o \
 | 
			
		||||
       buttons.o palette.o help.o operatio.o pages.o loadsave.o \
 | 
			
		||||
       buttons.o palette.o help.o operatio.o pages.o \
 | 
			
		||||
       readline.o engine.o filesel.o op_c.o readini.o saveini.o \
 | 
			
		||||
       shade.o keyboard.o io.o version.o text.o SFont.o setup.o \
 | 
			
		||||
       pxsimple.o pxtall.o pxwide.o pxdouble.o pxtriple.o \
 | 
			
		||||
       pxtall2.o pxtall3.o pxwide2.o pxquad.o \
 | 
			
		||||
       windows.o brush.o realpath.o mountlist.o input.o hotkeys.o \
 | 
			
		||||
       transform.o pversion.o factory.o $(PLATFORMOBJ) \
 | 
			
		||||
	   loadsave.o loadsavefuncs.o \
 | 
			
		||||
       fileformats.o miscfileformats.o libraw2crtc.o \
 | 
			
		||||
       brush_ops.o buttons_effects.o layers.o \
 | 
			
		||||
       oldies.o tiles.o colorred.o unicode.o gfx2surface.o \
 | 
			
		||||
 | 
			
		||||
@ -84,6 +84,7 @@
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
@ -5795,8 +5796,6 @@ void Load_PCX(T_IO_Context * context)
 | 
			
		||||
                            else
 | 
			
		||||
                              File_error=2;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                          Set_file_error(2);
 | 
			
		||||
                      }
 | 
			
		||||
                      else
 | 
			
		||||
                        buffer[x_pos++]=byte1;
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "unicode.h"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										278
									
								
								src/loadsave.c
									
									
									
									
									
								
							
							
						
						
									
										278
									
								
								src/loadsave.c
									
									
									
									
									
								
							@ -60,6 +60,7 @@
 | 
			
		||||
#include "keycodes.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "graph.h"
 | 
			
		||||
#include "op_c.h"
 | 
			
		||||
@ -260,7 +261,7 @@ void Fill_canvas(T_IO_Context *context, byte color)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Chargement des pixels dans le buffer 24b
 | 
			
		||||
/// Chargement des pixels dans le buffer 24b
 | 
			
		||||
void Set_pixel_24b(T_IO_Context *context, short x_pos, short y_pos, byte r, byte g, byte b)
 | 
			
		||||
{
 | 
			
		||||
  byte color;
 | 
			
		||||
@ -306,8 +307,6 @@ void Set_pixel_24b(T_IO_Context *context, short x_pos, short y_pos, byte r, byte
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Création d'une palette fake
 | 
			
		||||
void Set_palette_fake_24b(T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
@ -564,29 +563,6 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//                    Gestion des lectures et écritures                    //
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Write_one_byte(FILE *file, byte b)
 | 
			
		||||
{
 | 
			
		||||
  if (! Write_byte(file,b))
 | 
			
		||||
      File_error=1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// -------- Modifier la valeur du code d'erreur d'accès à un fichier --------
 | 
			
		||||
//   On n'est pas obligé d'utiliser cette fonction à chaque fois mais il est
 | 
			
		||||
// important de l'utiliser dans les cas du type:
 | 
			
		||||
//   if (!File_error) *** else File_error=***;
 | 
			
		||||
// En fait, dans le cas où l'on modifie File_error alors qu'elle contient
 | 
			
		||||
// dèjà un code d'erreur.
 | 
			
		||||
void Set_file_error(int value)
 | 
			
		||||
{
 | 
			
		||||
  if (File_error>=0)
 | 
			
		||||
    File_error=value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -- Charger n'importe connu quel type de fichier d'image (ou palette) -----
 | 
			
		||||
void Load_image(T_IO_Context *context)
 | 
			
		||||
@ -1956,6 +1932,7 @@ void Init_context_surface(T_IO_Context * context, char *file_name, char *file_di
 | 
			
		||||
  //context->Pitch
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Function to call when need to switch layers.
 | 
			
		||||
void Set_saving_layer(T_IO_Context *context, int layer)
 | 
			
		||||
{
 | 
			
		||||
@ -2297,252 +2274,3 @@ void Delete_safety_backups(void)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
FILE * Open_file_write(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f;
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
  if (context->File_name_unicode != NULL && context->File_name_unicode[0] != 0)
 | 
			
		||||
  {
 | 
			
		||||
    size_t len;
 | 
			
		||||
    WCHAR * filename_unicode;
 | 
			
		||||
 | 
			
		||||
    len = strlen(context->File_directory) + strlen(PATH_SEPARATOR)
 | 
			
		||||
        + Unicode_strlen(context->File_name_unicode) + 1;
 | 
			
		||||
    filename_unicode = (WCHAR *)GFX2_malloc(sizeof(WCHAR) * len);
 | 
			
		||||
    if (filename_unicode == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
 | 
			
		||||
    Unicode_char_strlcpy((word *)filename_unicode, context->File_directory, len);
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, PATH_SEPARATOR, len);
 | 
			
		||||
    Unicode_strlcat((word *)filename_unicode, context->File_name_unicode, len);
 | 
			
		||||
 | 
			
		||||
    f = _wfopen(filename_unicode, L"wb");
 | 
			
		||||
    if (f != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      // Now the file has been created, retrieve its short (ASCII) name
 | 
			
		||||
      len = GetShortPathNameW(filename_unicode, NULL, 0);
 | 
			
		||||
      if (len > 0)
 | 
			
		||||
      {
 | 
			
		||||
        WCHAR * shortpath = (WCHAR *)GFX2_malloc(sizeof(WCHAR) * len);
 | 
			
		||||
        if (shortpath != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          len = GetShortPathNameW(filename_unicode, shortpath, len);
 | 
			
		||||
          if (len > 0)
 | 
			
		||||
          {
 | 
			
		||||
            DWORD start, index;
 | 
			
		||||
            for (start = len; start > 0 && shortpath[start-1] != '\\'; start--);
 | 
			
		||||
            free(context->File_name);
 | 
			
		||||
            context->File_name = (char *)GFX2_malloc(len + 1 - start);
 | 
			
		||||
            if (context->File_name != NULL)
 | 
			
		||||
            {
 | 
			
		||||
              for (index = 0; index < len - start; index++)
 | 
			
		||||
                context->File_name[index] = shortpath[start + index];
 | 
			
		||||
              context->File_name[index] = '\0';
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    free(filename_unicode);
 | 
			
		||||
    return f;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
  if (filename == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  f = fopen(filename, "wb");
 | 
			
		||||
  free(filename);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f;
 | 
			
		||||
  char *p;
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
  if (context->File_name_unicode != NULL && context->File_name_unicode[0] != 0)
 | 
			
		||||
  {
 | 
			
		||||
    size_t len;
 | 
			
		||||
    WCHAR * filename_unicode;
 | 
			
		||||
    WCHAR * pw;
 | 
			
		||||
 | 
			
		||||
    len = strlen(context->File_directory) + strlen(PATH_SEPARATOR)
 | 
			
		||||
        + Unicode_strlen(context->File_name_unicode) + strlen(ext) + 1 + 1;
 | 
			
		||||
    filename_unicode = (WCHAR *)GFX2_malloc(len * sizeof(WCHAR));
 | 
			
		||||
    if (filename_unicode == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    Unicode_char_strlcpy((word *)filename_unicode, context->File_directory, len);
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, PATH_SEPARATOR, len);
 | 
			
		||||
    Unicode_strlcat((word *)filename_unicode, context->File_name_unicode, len);
 | 
			
		||||
    pw = wcschr(filename_unicode, (WCHAR)'.');
 | 
			
		||||
    if (pw != NULL)
 | 
			
		||||
      *pw = 0;
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, ".", len);
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, ext, len);
 | 
			
		||||
 | 
			
		||||
    f = _wfopen(filename_unicode, L"wb");
 | 
			
		||||
    free(filename_unicode);
 | 
			
		||||
    return f;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
// TODO: fix ! (realloc if not enough space)
 | 
			
		||||
  p = strrchr(filename, '.');
 | 
			
		||||
  if (p != NULL)
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
  strcat(filename, ".");
 | 
			
		||||
  strcat(filename, ext);
 | 
			
		||||
 | 
			
		||||
  f = fopen(filename, "wb");
 | 
			
		||||
  free(filename);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
			
		||||
FILE * Open_file_read(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f;
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
  f = fopen(filename, "rb");
 | 
			
		||||
  free(filename);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct T_Find_alternate_ext_data
 | 
			
		||||
{
 | 
			
		||||
  const char * ext;
 | 
			
		||||
  char * basename;
 | 
			
		||||
  word * basename_unicode;
 | 
			
		||||
  char * foundname;
 | 
			
		||||
  word * foundname_unicode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void Look_for_alternate_ext(void * pdata, const char * filename, const word * filename_unicode, byte is_file, byte is_directory, byte is_hidden)
 | 
			
		||||
{
 | 
			
		||||
  size_t base_len;
 | 
			
		||||
  struct T_Find_alternate_ext_data * params = (struct T_Find_alternate_ext_data *)pdata;
 | 
			
		||||
  (void)is_hidden;
 | 
			
		||||
  (void)is_directory;
 | 
			
		||||
 | 
			
		||||
  if (!is_file)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (filename_unicode != NULL && params->basename_unicode != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    if (params->foundname_unicode != NULL)
 | 
			
		||||
      return; // We already have found a file
 | 
			
		||||
    base_len = Unicode_strlen(params->basename_unicode);
 | 
			
		||||
    if (Unicode_strlen(filename_unicode) <= base_len)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
    if (filename_unicode[base_len] != '.')
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
    {
 | 
			
		||||
      int cmp;
 | 
			
		||||
      WCHAR * temp_string = (WCHAR *)GFX2_malloc((base_len + 1) * sizeof(WCHAR));
 | 
			
		||||
      if (temp_string == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
      memcpy(temp_string, filename_unicode, base_len * sizeof(word));
 | 
			
		||||
      temp_string[base_len] = 0;
 | 
			
		||||
      cmp = _wcsicmp((const WCHAR *)params->basename_unicode, temp_string);
 | 
			
		||||
      free(temp_string);
 | 
			
		||||
      if (cmp != 0)
 | 
			
		||||
        return; // No match.
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    if (memcmp(params->basename_unicode, filename_unicode, base_len * sizeof(word)) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#endif
 | 
			
		||||
    if (Unicode_char_strcasecmp(filename_unicode + base_len + 1, params->ext) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
    // it is a match !
 | 
			
		||||
    free(params->foundname);
 | 
			
		||||
    params->foundname_unicode = Unicode_strdup(filename_unicode);
 | 
			
		||||
    params->foundname = strdup(filename);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (params->foundname != NULL)
 | 
			
		||||
      return; // We already have found a file
 | 
			
		||||
    base_len = strlen(params->basename);
 | 
			
		||||
    if (filename[base_len] != '.')
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
    if (_memicmp(params->basename, filename, base_len) != 0)  // Not case sensitive
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#else
 | 
			
		||||
    if (memcmp(params->basename, filename, base_len) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#endif
 | 
			
		||||
    if (strcasecmp(filename + base_len + 1, params->ext) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
    params->foundname_unicode = NULL;
 | 
			
		||||
    params->foundname = strdup(filename);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f = NULL;
 | 
			
		||||
  char * p;
 | 
			
		||||
  struct T_Find_alternate_ext_data params;
 | 
			
		||||
 | 
			
		||||
  memset(¶ms, 0, sizeof(params));
 | 
			
		||||
  params.ext = ext;
 | 
			
		||||
  params.basename = strdup(context->File_name);
 | 
			
		||||
  if (params.basename == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GFX2_Log(GFX2_ERROR, "Open_file_read_with_alternate_ext() strdup() failed\n");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  p = strrchr(params.basename, '.');
 | 
			
		||||
  if (p != NULL)
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
  if (context->File_name_unicode != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    size_t i = Unicode_strlen(context->File_name_unicode);
 | 
			
		||||
    params.basename_unicode = GFX2_malloc(sizeof(word) * (i + 1));
 | 
			
		||||
    if (params.basename_unicode != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy(params.basename_unicode, context->File_name_unicode, (i + 1) * sizeof(word));
 | 
			
		||||
      while (i-- > 0)
 | 
			
		||||
        if (params.basename_unicode[i] == (word)'.')
 | 
			
		||||
        {
 | 
			
		||||
          params.basename_unicode[i] = 0;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  For_each_directory_entry(context->File_directory, ¶ms, Look_for_alternate_ext);
 | 
			
		||||
  if (params.foundname != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    char * filename; // filename with full path
 | 
			
		||||
 | 
			
		||||
    filename = Filepath_append_to_dir(context->File_directory, params.foundname);
 | 
			
		||||
    f = fopen(filename, "rb");
 | 
			
		||||
    free(filename);
 | 
			
		||||
  }
 | 
			
		||||
  free(params.basename);
 | 
			
		||||
  free(params.basename_unicode);
 | 
			
		||||
  free(params.foundname);
 | 
			
		||||
  free(params.foundname_unicode);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
void Remove_file(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
  Remove_path(filename);
 | 
			
		||||
  free(filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,9 +28,6 @@
 | 
			
		||||
#define __LOADSAVE_H__
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#if defined(USE_SDL) || defined(USE_SDL2)
 | 
			
		||||
#include <SDL_image.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "gfx2surface.h"
 | 
			
		||||
 | 
			
		||||
enum CONTEXT_TYPE {
 | 
			
		||||
@ -262,26 +259,8 @@ void Pixel_load_in_24b_preview(short x_pos,short y_pos,byte r,byte g,byte b);
 | 
			
		||||
*/
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
void Set_file_error(int value);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio);
 | 
			
		||||
*/
 | 
			
		||||
void Write_one_byte(FILE *file, byte b);
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
FILE * Open_file_write(T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
			
		||||
FILE * Open_file_read(T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
			
		||||
FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext);
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
void Remove_file(T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										308
									
								
								src/loadsavefuncs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								src/loadsavefuncs.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,308 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2019 Thomas Bernard
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
 | 
			
		||||
    Grafx2 is free software; you can redistribute it and/or
 | 
			
		||||
    modify it under the terms of the GNU General Public License
 | 
			
		||||
    as published by the Free Software Foundation; version 2
 | 
			
		||||
    of the License.
 | 
			
		||||
 | 
			
		||||
    Grafx2 is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Grafx2; if not, see <http://www.gnu.org/licenses/>
 | 
			
		||||
*/
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
///@file loadsavefuncs.c
 | 
			
		||||
/// helper functions for load/save
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "unicode.h"
 | 
			
		||||
#include "gfx2mem.h"
 | 
			
		||||
#include "gfx2log.h"
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
FILE * Open_file_write(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f;
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
  if (context->File_name_unicode != NULL && context->File_name_unicode[0] != 0)
 | 
			
		||||
  {
 | 
			
		||||
    size_t len;
 | 
			
		||||
    WCHAR * filename_unicode;
 | 
			
		||||
 | 
			
		||||
    len = strlen(context->File_directory) + strlen(PATH_SEPARATOR)
 | 
			
		||||
        + Unicode_strlen(context->File_name_unicode) + 1;
 | 
			
		||||
    filename_unicode = (WCHAR *)GFX2_malloc(sizeof(WCHAR) * len);
 | 
			
		||||
    if (filename_unicode == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
 | 
			
		||||
    Unicode_char_strlcpy((word *)filename_unicode, context->File_directory, len);
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, PATH_SEPARATOR, len);
 | 
			
		||||
    Unicode_strlcat((word *)filename_unicode, context->File_name_unicode, len);
 | 
			
		||||
 | 
			
		||||
    f = _wfopen(filename_unicode, L"wb");
 | 
			
		||||
    if (f != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      // Now the file has been created, retrieve its short (ASCII) name
 | 
			
		||||
      len = GetShortPathNameW(filename_unicode, NULL, 0);
 | 
			
		||||
      if (len > 0)
 | 
			
		||||
      {
 | 
			
		||||
        WCHAR * shortpath = (WCHAR *)GFX2_malloc(sizeof(WCHAR) * len);
 | 
			
		||||
        if (shortpath != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          len = GetShortPathNameW(filename_unicode, shortpath, len);
 | 
			
		||||
          if (len > 0)
 | 
			
		||||
          {
 | 
			
		||||
            DWORD start, index;
 | 
			
		||||
            for (start = len; start > 0 && shortpath[start-1] != '\\'; start--);
 | 
			
		||||
            free(context->File_name);
 | 
			
		||||
            context->File_name = (char *)GFX2_malloc(len + 1 - start);
 | 
			
		||||
            if (context->File_name != NULL)
 | 
			
		||||
            {
 | 
			
		||||
              for (index = 0; index < len - start; index++)
 | 
			
		||||
                context->File_name[index] = shortpath[start + index];
 | 
			
		||||
              context->File_name[index] = '\0';
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    free(filename_unicode);
 | 
			
		||||
    return f;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
  if (filename == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  f = fopen(filename, "wb");
 | 
			
		||||
  free(filename);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f;
 | 
			
		||||
  char *p;
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
  if (context->File_name_unicode != NULL && context->File_name_unicode[0] != 0)
 | 
			
		||||
  {
 | 
			
		||||
    size_t len;
 | 
			
		||||
    WCHAR * filename_unicode;
 | 
			
		||||
    WCHAR * pw;
 | 
			
		||||
 | 
			
		||||
    len = strlen(context->File_directory) + strlen(PATH_SEPARATOR)
 | 
			
		||||
        + Unicode_strlen(context->File_name_unicode) + strlen(ext) + 1 + 1;
 | 
			
		||||
    filename_unicode = (WCHAR *)GFX2_malloc(len * sizeof(WCHAR));
 | 
			
		||||
    if (filename_unicode == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    Unicode_char_strlcpy((word *)filename_unicode, context->File_directory, len);
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, PATH_SEPARATOR, len);
 | 
			
		||||
    Unicode_strlcat((word *)filename_unicode, context->File_name_unicode, len);
 | 
			
		||||
    pw = wcschr(filename_unicode, (WCHAR)'.');
 | 
			
		||||
    if (pw != NULL)
 | 
			
		||||
      *pw = 0;
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, ".", len);
 | 
			
		||||
    Unicode_char_strlcat((word *)filename_unicode, ext, len);
 | 
			
		||||
 | 
			
		||||
    f = _wfopen(filename_unicode, L"wb");
 | 
			
		||||
    free(filename_unicode);
 | 
			
		||||
    return f;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
// TODO: fix ! (realloc if not enough space)
 | 
			
		||||
  p = strrchr(filename, '.');
 | 
			
		||||
  if (p != NULL)
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
  strcat(filename, ".");
 | 
			
		||||
  strcat(filename, ext);
 | 
			
		||||
 | 
			
		||||
  f = fopen(filename, "wb");
 | 
			
		||||
  free(filename);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
			
		||||
FILE * Open_file_read(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f;
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
  f = fopen(filename, "rb");
 | 
			
		||||
  free(filename);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct T_Find_alternate_ext_data
 | 
			
		||||
{
 | 
			
		||||
  const char * ext;
 | 
			
		||||
  char * basename;
 | 
			
		||||
  word * basename_unicode;
 | 
			
		||||
  char * foundname;
 | 
			
		||||
  word * foundname_unicode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void Look_for_alternate_ext(void * pdata, const char * filename, const word * filename_unicode, byte is_file, byte is_directory, byte is_hidden)
 | 
			
		||||
{
 | 
			
		||||
  size_t base_len;
 | 
			
		||||
  struct T_Find_alternate_ext_data * params = (struct T_Find_alternate_ext_data *)pdata;
 | 
			
		||||
  (void)is_hidden;
 | 
			
		||||
  (void)is_directory;
 | 
			
		||||
 | 
			
		||||
  if (!is_file)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (filename_unicode != NULL && params->basename_unicode != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    if (params->foundname_unicode != NULL)
 | 
			
		||||
      return; // We already have found a file
 | 
			
		||||
    base_len = Unicode_strlen(params->basename_unicode);
 | 
			
		||||
    if (Unicode_strlen(filename_unicode) <= base_len)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
    if (filename_unicode[base_len] != '.')
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
    {
 | 
			
		||||
      int cmp;
 | 
			
		||||
      WCHAR * temp_string = (WCHAR *)GFX2_malloc((base_len + 1) * sizeof(WCHAR));
 | 
			
		||||
      if (temp_string == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
      memcpy(temp_string, filename_unicode, base_len * sizeof(word));
 | 
			
		||||
      temp_string[base_len] = 0;
 | 
			
		||||
      cmp = _wcsicmp((const WCHAR *)params->basename_unicode, temp_string);
 | 
			
		||||
      free(temp_string);
 | 
			
		||||
      if (cmp != 0)
 | 
			
		||||
        return; // No match.
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    if (memcmp(params->basename_unicode, filename_unicode, base_len * sizeof(word)) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#endif
 | 
			
		||||
    if (Unicode_char_strcasecmp(filename_unicode + base_len + 1, params->ext) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
    // it is a match !
 | 
			
		||||
    free(params->foundname);
 | 
			
		||||
    params->foundname_unicode = Unicode_strdup(filename_unicode);
 | 
			
		||||
    params->foundname = strdup(filename);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (params->foundname != NULL)
 | 
			
		||||
      return; // We already have found a file
 | 
			
		||||
    base_len = strlen(params->basename);
 | 
			
		||||
    if (filename[base_len] != '.')
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
    if (_memicmp(params->basename, filename, base_len) != 0)  // Not case sensitive
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#else
 | 
			
		||||
    if (memcmp(params->basename, filename, base_len) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
#endif
 | 
			
		||||
    if (strcasecmp(filename + base_len + 1, params->ext) != 0)
 | 
			
		||||
      return; // No match.
 | 
			
		||||
    params->foundname_unicode = NULL;
 | 
			
		||||
    params->foundname = strdup(filename);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext)
 | 
			
		||||
{
 | 
			
		||||
  FILE * f = NULL;
 | 
			
		||||
  char * p;
 | 
			
		||||
  struct T_Find_alternate_ext_data params;
 | 
			
		||||
 | 
			
		||||
  memset(¶ms, 0, sizeof(params));
 | 
			
		||||
  params.ext = ext;
 | 
			
		||||
  params.basename = strdup(context->File_name);
 | 
			
		||||
  if (params.basename == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GFX2_Log(GFX2_ERROR, "Open_file_read_with_alternate_ext() strdup() failed\n");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  p = strrchr(params.basename, '.');
 | 
			
		||||
  if (p != NULL)
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
  if (context->File_name_unicode != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    size_t i = Unicode_strlen(context->File_name_unicode);
 | 
			
		||||
    params.basename_unicode = GFX2_malloc(sizeof(word) * (i + 1));
 | 
			
		||||
    if (params.basename_unicode != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy(params.basename_unicode, context->File_name_unicode, (i + 1) * sizeof(word));
 | 
			
		||||
      while (i-- > 0)
 | 
			
		||||
        if (params.basename_unicode[i] == (word)'.')
 | 
			
		||||
        {
 | 
			
		||||
          params.basename_unicode[i] = 0;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  For_each_directory_entry(context->File_directory, ¶ms, Look_for_alternate_ext);
 | 
			
		||||
  if (params.foundname != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    char * filename; // filename with full path
 | 
			
		||||
 | 
			
		||||
    filename = Filepath_append_to_dir(context->File_directory, params.foundname);
 | 
			
		||||
    f = fopen(filename, "rb");
 | 
			
		||||
    free(filename);
 | 
			
		||||
  }
 | 
			
		||||
  free(params.basename);
 | 
			
		||||
  free(params.basename_unicode);
 | 
			
		||||
  free(params.foundname);
 | 
			
		||||
  free(params.foundname_unicode);
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
void Remove_file(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  char * filename; // filename with full path
 | 
			
		||||
 | 
			
		||||
  filename = Filepath_append_to_dir(context->File_directory, context->File_name);
 | 
			
		||||
  Remove_path(filename);
 | 
			
		||||
  free(filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Palette_256_to_64(T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i=0;i<256;i++)
 | 
			
		||||
  {
 | 
			
		||||
    palette[i].R = palette[i].R >> 2;
 | 
			
		||||
    palette[i].G = palette[i].G >> 2;
 | 
			
		||||
    palette[i].B = palette[i].B >> 2;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Palette_64_to_256(T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i=0;i<256;i++)
 | 
			
		||||
  {
 | 
			
		||||
    palette[i].R = (palette[i].R << 2)|(palette[i].R >> 4);
 | 
			
		||||
    palette[i].G = (palette[i].G << 2)|(palette[i].G >> 4);
 | 
			
		||||
    palette[i].B = (palette[i].B << 2)|(palette[i].B >> 4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								src/loadsavefuncs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/loadsavefuncs.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2019 Thomas Bernard
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
 | 
			
		||||
    Grafx2 is free software; you can redistribute it and/or
 | 
			
		||||
    modify it under the terms of the GNU General Public License
 | 
			
		||||
    as published by the Free Software Foundation; version 2
 | 
			
		||||
    of the License.
 | 
			
		||||
 | 
			
		||||
    Grafx2 is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Grafx2; if not, see <http://www.gnu.org/licenses/>
 | 
			
		||||
*/
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
///@file loadsavefuncs.h
 | 
			
		||||
/// helper functions for load/save
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef LOADSAVEFUNCS_H_INCLUDED
 | 
			
		||||
#define LOADSAVEFUNCS_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
FILE * Open_file_write(T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
			
		||||
FILE * Open_file_read(T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
			
		||||
FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext);
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
void Remove_file(T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
/// For use by Save_XXX() functions
 | 
			
		||||
FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext);
 | 
			
		||||
 | 
			
		||||
#define Write_one_byte(file, b) do { if (!Write_byte(file,(b))) File_error=1; } while (0)
 | 
			
		||||
 | 
			
		||||
void Palette_256_to_64(T_Palette palette);
 | 
			
		||||
void Palette_64_to_256(T_Palette palette);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -115,6 +115,7 @@
 | 
			
		||||
#include "engine.h"
 | 
			
		||||
#include "pages.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "screen.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "readini.h"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								src/misc.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/misc.c
									
									
									
									
									
								
							@ -400,28 +400,6 @@ byte Read_pixel_from_backup_screen (word x,word y)
 | 
			
		||||
  return *(Screen_backup + x + Main.image_width * y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Palette_256_to_64(T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i=0;i<256;i++)
 | 
			
		||||
  {
 | 
			
		||||
    palette[i].R = palette[i].R >> 2;
 | 
			
		||||
    palette[i].G = palette[i].G >> 2;
 | 
			
		||||
    palette[i].B = palette[i].B >> 2;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Palette_64_to_256(T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i=0;i<256;i++)
 | 
			
		||||
  {
 | 
			
		||||
    palette[i].R = (palette[i].R << 2)|(palette[i].R >> 4);
 | 
			
		||||
    palette[i].G = (palette[i].G << 2)|(palette[i].G >> 4);
 | 
			
		||||
    palette[i].B = (palette[i].B << 2)|(palette[i].B >> 4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte Effect_interpolated_colorize  (word x,word y,byte color)
 | 
			
		||||
{
 | 
			
		||||
  // factor_a = 256*(100-Colorize_opacity)/100
 | 
			
		||||
 | 
			
		||||
@ -47,8 +47,6 @@ void Wait_end_of_click(void);
 | 
			
		||||
void Set_color(byte color, byte red, byte green, byte blue);
 | 
			
		||||
const T_Components * Get_current_palette(void);
 | 
			
		||||
void Set_palette(T_Palette palette);
 | 
			
		||||
void Palette_256_to_64(T_Palette palette);
 | 
			
		||||
void Palette_64_to_256(T_Palette palette);
 | 
			
		||||
void Clear_current_image(byte color);
 | 
			
		||||
void Clear_current_image_with_stencil(byte color, byte * stencil);
 | 
			
		||||
dword Round_div(dword numerator,dword divisor);
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,7 @@
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "libraw2crtc.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "screen.h"
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@
 | 
			
		||||
#include "layers.h"
 | 
			
		||||
#include "graph.h"
 | 
			
		||||
#include "bitcount.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
 | 
			
		||||
// I don't have round() in MSVC++ 2010 (_MSC_VER=1600)
 | 
			
		||||
// or in mintlib
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "gfx2log.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user