diff --git a/README.md b/README.md index 1298ba2..713ce94 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,9 @@ Supported input formats are PNG, PDF, GIF, TIF, JPEG. Supported output formats are PNG, GIF, JPEG, TIFF. -Output formats are determined by the provided filename extension, -falling back to PNG. +Output formats are determined by the provided filename extension. +If no extension is provided, pngpaste infers the format from the +clipboard input and appends an extension automatically. It's unclear if EXIF data in JPEG sources are preserved. There's an issue with pasting into JPEG format from a GIF source. diff --git a/pngpaste.m b/pngpaste.m index 4651c89..c1302da 100644 --- a/pngpaste.m +++ b/pngpaste.m @@ -8,7 +8,7 @@ usage () { fprintf(stderr, - "Usage: %s [OPTIONS] \n" + "Usage: %s [OPTIONS] \n" "\t-\t" "Print to standard output" "\n" "\t-b\t" "Print to standard output as base64" "\n" "\t-v\t" "Version" "\n" @@ -129,6 +129,54 @@ return bitmapImageFileType; } +BOOL +hasFilenameExtension (NSString *filename) +{ + if (filename == nil) { + return NO; + } + return [[filename pathExtension] length] > 0; +} + +NSBitmapImageFileType +getBitmapImageFileTypeFromPasteboard (NSPasteboard *pasteBoard) +{ + NSBitmapImageFileType bitmapImageFileType = NSBitmapImageFileTypePNG; + if (pasteBoard != nil) { + NSArray *types = [pasteBoard types]; + for (NSString *type in types) { + if ([type isEqualToString:@"public.jpeg"]) { + return NSBitmapImageFileTypeJPEG; + } else if ([type isEqualToString:NSPasteboardTypePNG]) { + return NSBitmapImageFileTypePNG; + } else if ([type isEqualToString:@"com.compuserve.gif"]) { + return NSBitmapImageFileTypeGIF; + } else if ([type isEqualToString:NSPasteboardTypeTIFF]) { + return NSBitmapImageFileTypeTIFF; + } else if ([type isEqualToString:NSPasteboardTypePDF]) { + return NSBitmapImageFileTypePNG; + } + } + } + return bitmapImageFileType; +} + +NSString * +extensionForBitmapImageFileType (NSBitmapImageFileType bitmapImageFileType) +{ + switch (bitmapImageFileType) { + case NSBitmapImageFileTypeGIF: + return @"gif"; + case NSBitmapImageFileTypeJPEG: + return @"jpg"; + case NSBitmapImageFileTypeTIFF: + return @"tiff"; + case NSBitmapImageFileTypePNG: + default: + return @"png"; + } +} + /* * Returns NSData from Pasteboard Image if available; otherwise nil */ @@ -209,8 +257,18 @@ return EXIT_SUCCESS; } - NSBitmapImageFileType bitmapImageFileType = - getBitmapImageFileTypeFromFilename(params.outputFile); + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; + NSString *outputFile = params.outputFile; + NSBitmapImageFileType bitmapImageFileType; + if (hasFilenameExtension(outputFile)) { + bitmapImageFileType = getBitmapImageFileTypeFromFilename(outputFile); + } else { + bitmapImageFileType = getBitmapImageFileTypeFromPasteboard(pasteBoard); + if (outputFile != nil) { + NSString *extension = extensionForBitmapImageFileType(bitmapImageFileType); + outputFile = [outputFile stringByAppendingPathExtension:extension]; + } + } NSData *imageData = getPasteboardImageData(bitmapImageFileType); int exitCode; @@ -227,7 +285,7 @@ [stdout writeData:base64Data]; exitCode = EXIT_SUCCESS; } else { - if ([imageData writeToFile:params.outputFile atomically:YES]) { + if ([imageData writeToFile:outputFile atomically:YES]) { exitCode = EXIT_SUCCESS; } else { fatal("Could not write to file!");