diff --git a/ChangeLog b/ChangeLog index 61f1ab3404..9c840bb713 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2007-01-26 Tor Lillqvist + + Fix #398311 in GIMP until corresponding abstraction has been added + to GLib: + + * app/base/tile-private.h: Use gint64 instead of off_t. (I assume + the configury makes sure GIMP is always compiled as + large-file-aware on Unix with an off_t of at least 64 bits?) + + Introduce wrapper macros LARGE_SEEK() and LARGE_TRUNCATE(). On + Win32 LARGE_SEEK() calls _lseeki64() in the Microsoft C library, + and LARGE_TRUNCATE calls a new internal function + gimp_win32_large_truncate(). On Unix they call lseek() and + ftruncate(). + + * app/base/tile-swap.c: Use gint64 instead of off_t. Use + LARGE_SEEK() and LARGE_TRUNCATE() instead of lseek() and + ftruncate(). + (gimp_win32_large_truncate): New function. Calls LARGE_SEEK() and + SetEndOfFile(). + + * app/xcf/xcf-load.c (xcf_swap_func): Use LARGE_SEEK() instead of + lseek(). + 2007-01-26 Sven Neumann * app/tools/gimprectangletool.c: applied patch from Joao diff --git a/app/base/tile-private.h b/app/base/tile-private.h index 7e3e1601b2..8346b92e49 100644 --- a/app/base/tile-private.h +++ b/app/base/tile-private.h @@ -21,6 +21,20 @@ #include +#ifdef G_OS_WIN32 + +int gimp_win32_large_truncate (int fd, + gint64 size); + +#define LARGE_SEEK(f, o, w) _lseeki64 (f, o, w) +#define LARGE_TRUNCATE(f, s) gimp_win32_large_truncate (f, s) + +#else + +#define LARGE_SEEK(f, o, t) lseek (f, o, t) +#define LARGE_TRUNCATE(f, s) ftruncate (f, s) + +#endif typedef struct _TileLink TileLink; @@ -69,7 +83,7 @@ struct _Tile * for swapping. swap_num 1 is always the global * swap file. */ - off_t swap_offset; /* the offset within the swap file of the tile data. + gint64 swap_offset; /* the offset within the swap file of the tile data. * if the tile data is in memory this will be set * to -1. */ diff --git a/app/base/tile-swap.c b/app/base/tile-swap.c index e561ac825f..e39f9c4c75 100644 --- a/app/base/tile-swap.c +++ b/app/base/tile-swap.c @@ -33,6 +33,7 @@ #include "libgimpconfig/gimpconfig.h" #ifdef G_OS_WIN32 +#include #include "libgimpbase/gimpwin32-io.h" #include #define getpid _getpid @@ -72,14 +73,14 @@ struct _SwapFile struct _DefSwapFile { GList *gaps; - off_t swap_file_end; - off_t cur_position; + gint64 swap_file_end; + gint64 cur_position; }; struct _Gap { - off_t start; - off_t end; + gint64 start; + gint64 end; }; struct _AsyncSwapArgs @@ -110,14 +111,15 @@ static void tile_swap_default_out (DefSwapFile *def_swap_file, static void tile_swap_default_delete (DefSwapFile *def_swap_file, gint fd, Tile *tile); -static off_t tile_swap_find_offset (DefSwapFile *def_swap_file, + +static gint64 tile_swap_find_offset (DefSwapFile *def_swap_file, gint fd, - off_t bytes); + gint64 bytes); static void tile_swap_resize (DefSwapFile *def_swap_file, gint fd, - off_t new_size); -static Gap * tile_swap_gap_new (off_t start, - off_t end); + gint64 new_size); +static Gap * tile_swap_gap_new (gint64 start, + gint64 end); static void tile_swap_gap_destroy (Gap *gap); @@ -126,12 +128,27 @@ static GHashTable * swap_files = NULL; static GList * open_swap_files = NULL; static gint nopen_swap_files = 0; static gint next_swap_num = 1; -static const off_t swap_file_grow = 1024 * TILE_WIDTH * TILE_HEIGHT * 4; + +static const gint64 swap_file_grow = 1024 * TILE_WIDTH * TILE_HEIGHT * 4; static gboolean seek_err_msg = TRUE; static gboolean read_err_msg = TRUE; static gboolean write_err_msg = TRUE; +#ifdef G_OS_WIN32 + +int +gimp_win32_large_truncate (int fd, + gint64 size) +{ + if (LARGE_SEEK (fd, size, SEEK_SET) == size && + SetEndOfFile ((HANDLE) _get_osfhandle (fd))) + return 0; + else + return -1; +} + +#endif #ifdef GIMP_UNSTABLE static void @@ -467,8 +484,8 @@ tile_swap_default_in (DefSwapFile *def_swap_file, gint fd, Tile *tile) { - gint nleft; - off_t offset; + gint nleft; + gint64 offset; if (tile->data) return; @@ -477,7 +494,7 @@ tile_swap_default_in (DefSwapFile *def_swap_file, { def_swap_file->cur_position = tile->swap_offset; - offset = lseek (fd, tile->swap_offset, SEEK_SET); + offset = LARGE_SEEK (fd, tile->swap_offset, SEEK_SET); if (offset == -1) { if (seek_err_msg) @@ -527,10 +544,10 @@ tile_swap_default_out (DefSwapFile *def_swap_file, int fd, Tile *tile) { - gint bytes; - gint nleft; - off_t offset; - off_t newpos; + gint bytes; + gint nleft; + gint64 offset; + gint64 newpos; bytes = TILE_WIDTH * TILE_HEIGHT * tile->bpp; @@ -542,7 +559,7 @@ tile_swap_default_out (DefSwapFile *def_swap_file, if (def_swap_file->cur_position != newpos) { - offset = lseek (fd, newpos, SEEK_SET); + offset = LARGE_SEEK (fd, newpos, SEEK_SET); if (offset == -1) { if (seek_err_msg) @@ -592,8 +609,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file, GList *tmp2; Gap *gap; Gap *gap2; - off_t start; - off_t end; + gint64 start; + gint64 end; if (tile->swap_offset == -1) return; @@ -692,11 +709,11 @@ tile_swap_default_delete (DefSwapFile *def_swap_file, static void tile_swap_resize (DefSwapFile *def_swap_file, gint fd, - off_t new_size) + gint64 new_size) { if (def_swap_file->swap_file_end > new_size) { - if (ftruncate (fd, new_size) != 0) + if (LARGE_TRUNCATE (fd, new_size) != 0) { g_message ("Failed to resize swap file: %s", g_strerror (errno)); return; @@ -706,14 +723,14 @@ tile_swap_resize (DefSwapFile *def_swap_file, def_swap_file->swap_file_end = new_size; } -static off_t +static gint64 tile_swap_find_offset (DefSwapFile *def_swap_file, gint fd, - off_t bytes) + gint64 bytes) { GList *tmp; Gap *gap; - off_t offset; + gint64 offset; tmp = def_swap_file->gaps; while (tmp) @@ -754,8 +771,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file, } static Gap * -tile_swap_gap_new (off_t start, - off_t end) +tile_swap_gap_new (gint64 start, + gint64 end) { Gap *gap = g_new (Gap, 1); diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index a9833ae360..b32aaff6a3 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -1819,7 +1819,7 @@ xcf_swap_func (gint fd, switch (cmd) { case SWAP_IN: - lseek (fd, tile->swap_offset, SEEK_SET); + LARGE_SEEK (fd, tile->swap_offset, SEEK_SET); bytes = tile_size (tile); tile_alloc (tile);