diff --git a/src/fileformats.h b/src/fileformats.h index c1525836..a5e11f5a 100644 --- a/src/fileformats.h +++ b/src/fileformats.h @@ -168,6 +168,7 @@ void Test_TIFF(T_IO_Context *, FILE *); void Load_TIFF(T_IO_Context *); void Save_TIFF(T_IO_Context *); void Load_TIFF_from_memory(T_IO_Context *, const void *, unsigned long); +void Save_TIFF_to_memory(T_IO_Context *, void * *, unsigned long *); #endif /// @} diff --git a/src/filesel.c b/src/filesel.c index c4ec3cb5..766d9d1d 100644 --- a/src/filesel.c +++ b/src/filesel.c @@ -1736,10 +1736,8 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context #if defined(WIN32) || defined(__macosx__) || defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11)) if (load) Window_set_normal_button(62,180,115,14,"From Clipboard",0,1,SHORTCUT_PASTE); // 14 -#if !defined(__macosx__) else Window_set_normal_button(62,180,115,14,"To Clipboard",0,1,SHORTCUT_COPY); // 14 -#endif #endif Change_directory(context->File_directory); diff --git a/src/loadsave.c b/src/loadsave.c index 6f489c84..ac82593e 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -88,6 +88,7 @@ extern Window X11_window; #if defined(__macosx__) const void * get_tiff_paste_board(unsigned long * size); +int set_tiff_paste_board(const void * tiff, unsigned long size); #endif @@ -1583,6 +1584,18 @@ static void Save_ClipBoard_Image(T_IO_Context * context) } } CloseClipboard(); +#elif defined(__macosx__) + void * tiff = NULL; + unsigned long size = 0; + + Save_TIFF_to_memory(context, &tiff, &size); + if (File_error == 0 && tiff != NULL) + { + if(!set_tiff_paste_board(tiff, size)) + File_error = 1; + } + free(tiff); + #elif defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11)) Atom selection; #if defined(SDL_VIDEO_DRIVER_X11) diff --git a/src/pasteboard.m b/src/pasteboard.m index ba04a5d4..4f723122 100644 --- a/src/pasteboard.m +++ b/src/pasteboard.m @@ -35,3 +35,17 @@ const void * get_tiff_paste_board(unsigned long * size) *size = [data length]; return [data bytes]; } + +int set_tiff_paste_board(const void * tiff, unsigned long size) +{ + if (tiff == NULL || size == 0) + return 0; + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard declareTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil]; + NSData *data = [[NSData alloc] initWithBytes:tiff length:size]; + BOOL b = [pasteboard setData:data forType:NSTIFFPboardType]; + if (!b) + NSLog(@"Failed to set data in pasteboard"); + [data release]; + return (int)b; +} diff --git a/src/tifformat.c b/src/tifformat.c index 493cf371..5b163eca 100644 --- a/src/tifformat.c +++ b/src/tifformat.c @@ -396,6 +396,7 @@ struct memory_buffer char * buffer; unsigned long offset; unsigned long size; + unsigned long alloc_size; }; tmsize_t lTIFF_read(thandle_t p, void * data, tmsize_t size) @@ -409,15 +410,29 @@ tmsize_t lTIFF_read(thandle_t p, void * data, tmsize_t size) tmsize_t lTIFF_write(thandle_t p, void * data, tmsize_t size) { - //struct memory_buffer * mbuffer = (struct memory_buffer *)p; + struct memory_buffer * mbuffer = (struct memory_buffer *)p; GFX2_Log(GFX2_DEBUG, "lTIFF_write(%p, %p, %u)\n", p, data, size); - return -1; + if (mbuffer->offset + size > mbuffer->alloc_size) + { + char * tmp = realloc(mbuffer->buffer, mbuffer->offset + size + 1024); + if (tmp == NULL) + { + GFX2_Log(GFX2_ERROR, "lTIFF_write() failed to allocate %u bytes of memory\n", mbuffer->offset + size + 1024); + return -1; + } + mbuffer->buffer = tmp; + mbuffer->alloc_size = mbuffer->offset + size + 1024; + } + memcpy(mbuffer->buffer + mbuffer->offset, data, size); + mbuffer->offset += size; + if (mbuffer->offset > mbuffer->size) + mbuffer->size = mbuffer->offset; + return size; } toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence) { struct memory_buffer * mbuffer = (struct memory_buffer *)p; - GFX2_Log(GFX2_DEBUG, "lTIFF_seek(%p, %u, %d)\n", p, offset, whence); switch (whence) { case SEEK_SET: @@ -432,6 +447,25 @@ toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence) default: return -1; } + GFX2_Log(GFX2_DEBUG, "lTIFF_seek(%p, %u, %d) new offset=%u (size=%u)\n", + p, offset, whence, mbuffer->offset, mbuffer->size); + if (mbuffer->offset > mbuffer->alloc_size) + { + char * tmp = realloc(mbuffer->buffer, mbuffer->offset + 1024); + if (tmp == NULL) + { + GFX2_Log(GFX2_ERROR, "lTIFF_seek() failed to allocate %u bytes of memory\n", mbuffer->offset + 1024); + return -1; + } + mbuffer->buffer = tmp; + mbuffer->alloc_size = mbuffer->offset + 1024; + } + if (mbuffer->offset > mbuffer->size) + { + memset(mbuffer->buffer + mbuffer->size, 0, mbuffer->offset - mbuffer->size); + GFX2_Log(GFX2_ERROR, " seeking %d bytes after end of buffer, filling with 0s\n", mbuffer->offset - mbuffer->size); + mbuffer->size = mbuffer->offset; + } return mbuffer->offset; } @@ -439,6 +473,7 @@ toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence) toff_t lTIFF_size(thandle_t p) { struct memory_buffer * mbuffer = (struct memory_buffer *)p; + GFX2_Log(GFX2_DEBUG, "lTIFF_size(%p) = %u\n", p, mbuffer->size); return mbuffer->size; } @@ -472,6 +507,7 @@ void Load_TIFF_from_memory(T_IO_Context * context, const void * buffer, unsigned memory_buffer.buffer = (char *)buffer; memory_buffer.offset = 0; memory_buffer.size = size; + memory_buffer.alloc_size = 0; // unused for read TIFF_Init(); tif = TIFFClientOpen("memory.tiff", "r", &memory_buffer, @@ -610,6 +646,30 @@ void Save_TIFF_Sub(T_IO_Context * context, TIFF * tif) } } +/// Save TIFF to memory +void Save_TIFF_to_memory(T_IO_Context * context, void * * buffer, unsigned long * size) +{ + TIFF * tif; + struct memory_buffer memory_buffer; + + memory_buffer.buffer = NULL; + memory_buffer.offset = 0; + memory_buffer.size = 0; + memory_buffer.alloc_size = 0; + + TIFF_Init(); + tif = TIFFClientOpen("memory.tiff", "w", &memory_buffer, + lTIFF_read, lTIFF_write, lTIFF_seek, lTIFF_close, + lTIFF_size, lTIFF_map, lTIFF_unmap); + if (tif != NULL) + { + Save_TIFF_Sub(context, tif); + TIFFClose(tif); + *buffer = memory_buffer.buffer; + *size = memory_buffer.size; + } +} + /// Save TIFF void Save_TIFF(T_IO_Context * context) {