summaryrefslogtreecommitdiffstats
path: root/hacks/webcollage-helper-cocoa.m
diff options
context:
space:
mode:
authorSimon Rettberg2024-09-06 14:42:37 +0200
committerSimon Rettberg2024-09-06 14:42:37 +0200
commitbadef32037f52f79abc1f1440b786cd71afdf270 (patch)
tree412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/webcollage-helper-cocoa.m
parentDelete pre-6.00 files (diff)
downloadxscreensaver-master.tar.gz
xscreensaver-master.tar.xz
xscreensaver-master.zip
Diffstat (limited to 'hacks/webcollage-helper-cocoa.m')
-rw-r--r--hacks/webcollage-helper-cocoa.m510
1 files changed, 0 insertions, 510 deletions
diff --git a/hacks/webcollage-helper-cocoa.m b/hacks/webcollage-helper-cocoa.m
deleted file mode 100644
index fde1f0d..0000000
--- a/hacks/webcollage-helper-cocoa.m
+++ /dev/null
@@ -1,510 +0,0 @@
-/* webcollage-helper-cocoa --- scales and pastes one image into another
- * xscreensaver, Copyright (c) 2002-2018 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-/* This is the Cocoa implementation. See webcollage-helper.c for the
- GDK + JPEGlib implementation.
- */
-
-#import <Cocoa/Cocoa.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
- typedef int NSInteger;
- typedef unsigned int NSUInteger;
-#endif
-
-
-char *progname;
-static int verbose_p = 0;
-
-static void write_image (NSImage *img, const char *file);
-
-
-/* NSImage can't load PPMs by default...
- */
-static NSImage *
-load_ppm_image (const char *file)
-{
- FILE *in = fopen (file, "r");
- if (! in) return 0;
-
- char buf[255];
-
- char *s = fgets (buf, sizeof(buf)-1, in); /* P6 */
- if (!s || !!strcmp (s, "P6\n"))
- return 0;
-
- s = fgets (buf, sizeof(buf)-1, in); /* W H */
- if (!s)
- return 0;
-
- int w = 0, h = 0, d = 0;
- if (2 != sscanf (buf, " %d %d \n", &w, &h))
- return 0;
- if (w <= 0 || h <= 0)
- return 0;
-
- s = fgets (buf, sizeof(buf)-1, in); /* 255 */
- if (!s)
- return 0;
-
- if (1 != sscanf (buf, " %d \n", &d))
- return 0;
- if (d != 255)
- return 0;
-
- int size = (w * (h+1) * 3);
- unsigned char *bits = malloc (size);
- if (!bits) return 0;
-
- int n = read (fileno (in), (void *) bits, size); /* body */
- if (n < 20) return 0;
-
- fclose (in);
-
- NSBitmapImageRep *rep =
- [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes: &bits
- pixelsWide: w
- pixelsHigh: h
- bitsPerSample: 8
- samplesPerPixel: 3
- hasAlpha: NO
- isPlanar: NO
- colorSpaceName: NSDeviceRGBColorSpace
- bitmapFormat: NSAlphaFirstBitmapFormat
- bytesPerRow: w * 3
- bitsPerPixel: 8 * 3];
-
- NSImage *image = [[NSImage alloc] initWithSize: NSMakeSize (w, h)];
- [image addRepresentation: rep];
- [rep release];
-
- // #### 'bits' is leaked... the NSImageRep doesn't free it when freed.
-
- return image;
-}
-
-
-static NSImage *
-load_image (const char *file)
-{
- NSImage *image = [[NSImage alloc]
- initWithContentsOfFile:
- [NSString stringWithCString: file
- encoding: NSUTF8StringEncoding]];
- if (! image)
- image = load_ppm_image (file);
-
- if (! image) {
- fprintf (stderr, "%s: unable to load %s\n", progname, file);
- exit (1);
- }
-
-
- // [NSImage size] defaults to the image size in points instead of pixels,
- // so if an image file specified "pixels per inch" we can end up with
- // absurdly sized images. Set it back to 1:1 pixel:point.
- //
- NSImageRep *rep = [image.representations objectAtIndex:0];
- image.size = NSMakeSize (rep.pixelsWide, rep.pixelsHigh);
-
- return image;
-}
-
-
-static void
-bevel_image (NSImage *img, int bevel_pct,
- int x, int y, int w, int h, double scale)
-{
- int small_size = (w > h ? h : w);
-
- int bevel_size = small_size * (bevel_pct / 100.0);
-
- bevel_size /= scale;
-
- /* Use a proportionally larger bevel size for especially small images. */
- if (bevel_size < 20 && small_size > 40) bevel_size = 20;
- else if (bevel_size < 10 && small_size > 20) bevel_size = 10;
- else if (bevel_size < 5) /* too small to bother bevelling */
- return;
-
-
- NSBitmapImageRep *rep =
- [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes: NULL
- pixelsWide: w
- pixelsHigh: h
- bitsPerSample: 8
- samplesPerPixel: 4
- hasAlpha: YES
- isPlanar: NO
- colorSpaceName: NSDeviceRGBColorSpace
- bitmapFormat: NSAlphaFirstBitmapFormat
- bytesPerRow: 0
- bitsPerPixel: 0];
-
- NSInteger xx, yy;
- double *ramp = (double *) malloc (sizeof(*ramp) * (bevel_size + 1));
-
- if (!ramp)
- {
- fprintf (stderr, "%s: out of memory (%d)\n", progname, bevel_size);
- exit (1);
- }
-
- for (xx = 0; xx <= bevel_size; xx++)
- {
-# if 0 /* linear */
- ramp[xx] = xx / (double) bevel_size;
-
-# else /* sinusoidal */
- double p = (xx / (double) bevel_size);
- double s = sin (p * M_PI / 2);
- ramp[xx] = s;
-# endif
- }
-
- memset ([rep bitmapData], 0xFFFFFFFF,
- [rep bytesPerRow] * h);
-
- for (yy = 0; yy < h; yy++)
- {
- for (xx = 0; xx < w; xx++)
- {
- double rx, ry, r;
-
- if (xx < bevel_size) rx = ramp[xx];
- else if (xx >= w - bevel_size) rx = ramp[w - xx - 1];
- else rx = 1;
-
- if (yy < bevel_size) ry = ramp[yy];
- else if (yy >= h - bevel_size) ry = ramp[h - yy - 1];
- else ry = 1;
-
- r = rx * ry;
- if (r != 1)
- {
- NSUInteger p[4];
- p[0] = 0xFF * r;
- p[1] = p[2] = p[3] = 0xFF;
- [rep setPixel:p atX:xx y:yy];
- }
- }
- }
-
- free (ramp);
-
- NSImage *bevel_img = [[NSImage alloc]
- initWithData: [rep TIFFRepresentation]];
-
- [img lockFocus];
- y = [img size].height - (y + h);
- [bevel_img drawAtPoint: NSMakePoint (x, y)
- fromRect: NSMakeRect (0, 0, w, h)
- operation: NSCompositeDestinationIn /* Destination image
- wherever both images are
- opaque, transparent
- elsewhere. */
- fraction: 1.0];
- [img unlockFocus];
-
- [rep release];
- [bevel_img release];
-
- if (verbose_p)
- fprintf (stderr, "%s: added %d%% bevel (%d px)\n", progname,
- bevel_pct, bevel_size);
-}
-
-
-static void
-paste (const char *paste_file,
- const char *base_file,
- double from_scale,
- double opacity, int bevel_pct,
- int from_x, int from_y, int to_x, int to_y,
- int w, int h)
-{
- NSImage *paste_img = load_image (paste_file);
- NSImage *base_img = load_image (base_file);
-
- int paste_w = [paste_img size].width;
- int paste_h = [paste_img size].height;
-
- int base_w = [base_img size].width;
- int base_h = [base_img size].height;
-
- if (verbose_p)
- {
- fprintf (stderr, "%s: loaded %s: %dx%d\n",
- progname, base_file, base_w, base_h);
- fprintf (stderr, "%s: loaded %s: %dx%d\n",
- progname, paste_file, paste_w, paste_h);
- }
-
- if (bevel_pct > 0 && paste_w > 5 && paste_h > 5)
- bevel_image (paste_img, bevel_pct,
- from_x, from_y, w, h,
- from_scale);
-
- int scaled_w = w * from_scale;
- int scaled_h = h * from_scale;
-
- from_y = paste_h - (from_y + h); // Cocoa flipped coordinate system
- to_y = base_h - (to_y + scaled_h);
-
- [base_img lockFocus];
- [paste_img drawInRect: NSMakeRect (to_x, to_y, scaled_w, scaled_h)
- fromRect: NSMakeRect (from_x, from_y, w, h)
- operation: NSCompositeSourceOver
- fraction: opacity];
- [base_img unlockFocus];
-
- if (verbose_p)
- fprintf (stderr, "%s: pasted %dx%d (%dx%d) from %d,%d to %d,%d\n",
- progname, w, h, scaled_w, scaled_h, from_x, from_y, to_x, to_y);
-
- [paste_img release];
- write_image (base_img, base_file);
- [base_img release];
-}
-
-
-static NSColor *
-parse_color (const char *s)
-{
- static const char hex[128] =
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
- 0, 10,11,12,13,14,15,0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 10,11,12,13,14,15,0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- unsigned char r=0, g=0, b=0;
-
- if (!strcasecmp (s, "black")) ;
- else if (!strcasecmp (s, "white")) r = g = b = 0xFF;
- else if (!strcasecmp (s, "red")) r = 0xFF;
- else if (!strcasecmp (s, "green")) g = 0xFF;
- else if (!strcasecmp (s, "blue")) b = 0xFF;
- else
- {
- if (*s != '#' || strlen(s) != 7)
- {
- fprintf (stderr, "%s: unparsable color: \"%s\"\n", progname, s);
- exit (1);
- }
- s++;
- r = (hex[(int) s[0]] << 4) | hex[(int) s[1]], s += 2;
- g = (hex[(int) s[0]] << 4) | hex[(int) s[1]], s += 2;
- b = (hex[(int) s[0]] << 4) | hex[(int) s[1]], s += 2;
- }
-
- return [NSColor colorWithRed: r / 255.0
- green: g / 255.0
- blue: b / 255.0
- alpha: 1.0];
-}
-
-
-static void
-create (const char *color,
- int w, int h,
- const char *file)
-{
- NSColor *c = parse_color (color);
- NSImage *img = [[NSImage alloc] initWithSize:NSMakeSize(w, h)];
- [img lockFocus];
- [c drawSwatchInRect:NSMakeRect(0, 0, w, h)];
- [img unlockFocus];
- write_image (img, file);
- [img release];
-}
-
-
-static void
-write_image (NSImage *img, const char *file)
-{
- float jpeg_quality = .85;
-
- // Load the NSImage's contents into an NSBitmapImageRep.
-
-#if 0
- // If the local display is Retina, this doubles the size of the output JPEG.
- NSBitmapImageRep *bit_rep = [NSBitmapImageRep
- imageRepWithData:[img TIFFRepresentation]];
-#else
- // Render the image into a rep using pixels instead of points.
- NSBitmapImageRep *bit_rep = [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes:NULL
- pixelsWide:[img size].width
- pixelsHigh:[img size].height
- bitsPerSample:8
- samplesPerPixel:4
- hasAlpha:YES
- isPlanar:NO
- colorSpaceName:NSCalibratedRGBColorSpace
- bytesPerRow:0
- bitsPerPixel:0];
- bit_rep.size = [img size];
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:
- [NSGraphicsContext
- graphicsContextWithBitmapImageRep:bit_rep]];
- [img drawInRect:NSMakeRect(0, 0, [img size].width, [img size].height)
- fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
- [NSGraphicsContext restoreGraphicsState];
-#endif
-
- // Write the bitmapImageRep to a JPEG file.
- if (bit_rep == nil)
- {
- fprintf (stderr, "%s: error converting image?\n", progname);
- exit (1);
- }
-
- if (verbose_p)
- fprintf (stderr, "%s: writing %s (q=%d%%) ", progname, file,
- (int) (jpeg_quality * 100));
-
- NSData *jpeg_data = [bit_rep representationUsingType:NSJPEGFileType
- properties:@{ NSImageCompressionFactor:
- [NSNumber numberWithFloat:
- jpeg_quality] }];
- [jpeg_data writeToFile:
- [NSString stringWithCString:file
- encoding:NSISOLatin1StringEncoding]
- atomically:YES];
-
- if (verbose_p)
- {
- struct stat st;
- if (stat (file, &st))
- {
- char buf[255];
- sprintf (buf, "%.100s: %.100s", progname, file);
- perror (buf);
- exit (1);
- }
- fprintf (stderr, " %luK\n", ((unsigned long) st.st_size + 1023) / 1024);
- }
-}
-
-
-static void
-usage (void)
-{
- fprintf (stderr,
- "\nusage: %s [-v] paste-file base-file\n"
- "\t from-scale opacity\n"
- "\t from-x from-y to-x to-y w h\n"
- "\n"
- "\t Pastes paste-file into base-file.\n"
- "\t base-file will be overwritten (with JPEG data.)\n"
- "\t scaling is applied first: coordinates apply to scaled image.\n"
- "\n"
- "usage: %s [-v] color width height output-file\n"
- "\t Creates a new image of a solid color.\n\n",
- progname, progname);
- exit (1);
-}
-
-
-int
-main (int argc, char **argv)
-{
- int i;
- char *paste_file, *base_file, *s, dummy;
- double from_scale, opacity;
- int from_x, from_y, to_x, to_y, w, h, bevel_pct;
-
- i = 0;
- progname = argv[i++];
- s = strrchr (progname, '/');
- if (s) progname = s+1;
-
- // Much of Cocoa needs one of these to be available.
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- //Need an NSApp instance to make [NSImage TIFFRepresentation] work
- NSApp = [NSApplication sharedApplication];
- [NSApp autorelease];
-
- if (!strcmp(argv[i], "-v"))
- verbose_p++, i++;
-
- if (argc == 11 || argc == 12)
- {
- paste_file = argv[i++];
- base_file = argv[i++];
-
- if (*paste_file == '-') usage();
- if (*base_file == '-') usage();
-
- s = argv[i++];
- if (1 != sscanf (s, " %lf %c", &from_scale, &dummy)) usage();
- if (from_scale <= 0 || from_scale > 100) usage();
-
- s = argv[i++];
- if (1 != sscanf (s, " %lf %c", &opacity, &dummy)) usage();
- if (opacity <= 0 || opacity > 1) usage();
-
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &from_x, &dummy)) usage();
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &from_y, &dummy)) usage();
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &to_x, &dummy)) usage();
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &to_y, &dummy)) usage();
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &w, &dummy)) usage();
- s = argv[i]; if (1 != sscanf (s, " %d %c", &h, &dummy)) usage();
-
- bevel_pct = 10; /* #### */
-
- if (w < 0) usage();
- if (h < 0) usage();
-
- if (w == 0 || h == 0 ||
- w > 10240 || h > 10240) {
- fprintf (stderr, "%s: absurd size: %d x %d\n", progname, w, h);
- exit (1);
- }
-
- paste (paste_file, base_file,
- from_scale, opacity, bevel_pct,
- from_x, from_y, to_x, to_y,
- w, h);
- }
- else if (argc == 4 || argc == 5)
- {
- char *color = argv[i++];
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &w, &dummy)) usage();
- s = argv[i++]; if (1 != sscanf (s, " %d %c", &h, &dummy)) usage();
- paste_file = argv[i++];
- if (*paste_file == '-') usage();
-
- create (color, w, h, paste_file);
- }
- else
- {
- usage();
- }
-
- [pool release];
-
- exit (0);
-}