<commit_before>/*
 * zoom - Interpolate images with a cosine basis at arbitrary scales/offsets.
 * Copyright 2013-2016 0x09.net.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <wand/MagickWand.h>
#include <getopt.h>

#include <fftw3.h>

#include "longmath.h"

enum basis {
	INTERPOLATED = 0,
	CENTERED,
	NATIVE,
	UNITARY
};

void usage(const char* self) {
	printf("usage: %s -s scale -p pos -v viewport --basis=interpolated,centered,native,unitary -c --showsamples=1(point),2(grid) input output\n",self);
	exit(0);
}

int main(int argc, char* argv[]) {
	long double vx = 0, vy = 0;
	size_t vw = 0, vh = 0;
	bool vflag = false, centered = false;
	int showsamples = 0;
	long double scale_num = 1;
	unsigned long long scale_den = 1;
	int basis = INTERPOLATED;
	int c;
	const struct option opts[] = {
		{"showsamples",optional_argument,NULL,1},
		{"basis",required_argument,NULL,2},
		{0}
	};

	while((c = getopt_long(argc,argv,"s:v:p:c",opts,&optind)) != -1) {
		switch(c) {
			case  0 : break;
			case 's': sscanf(optarg,"%Lf/%llu",&scale_num,&scale_den); break;
			case 'v': sscanf(optarg,"%zux%zu",&vw,&vh); break;
			case 'p': sscanf(optarg,"%Lfx%Lf",&vx,&vy); break;
			case 'c': centered = true; break;
			case 1: showsamples = strtol(optarg,NULL,10); break;
			case 2: {
				if(!strcmp(optarg,"centered"))
					basis = CENTERED;
				else if(!strcmp(optarg,"native"))
					basis = NATIVE;
				else if(!strcmp(optarg,"unitary"))
					basis = UNITARY;
			}; break;
			default: usage(argv[0]);
		}
	}

	if(argc-optind < 2)
		usage(argv[0]);

	const char* infile = argv[optind++],* outfile = argv[optind++];

	MagickWandGenesis();
	MagickWand* wand = NewMagickWand();
	if(MagickReadImage(wand,infile) == MagickFalse) {
		DestroyMagickWand(wand);
		MagickWandTerminus();
		return 1;
	}
	size_t width = MagickGetImageWidth(wand), height = MagickGetImageHeight(wand);
	if(!vw) vw = width*scale_num/scale_den;
	if(!vh) vh = height*scale_num/scale_den;

	double* coeffs = malloc(sizeof(double)*width*height*3);
	MagickExportImagePixels(wand,0,0,width,height,"RGB",DoublePixel,coeffs);

	if(centered) {
		vx = vx*scale_num/scale_den - vw/2.L;
		vy = vy*scale_num/scale_den - vh/2.L;
	}
	long double scale = scale_num / scale_den;
	size_t nwidth = round(width * scale_num / scale_den), nheight = round(height * scale_num / scale_den);
	size_t cwidth = nwidth < width ? nwidth : width, cheight = nheight < height ? nheight : height;
	unsigned char* icoeffs = malloc(vw*vh*3);
	double* tmp = malloc(sizeof(double)*cheight);
	double* twiddles[2] = {malloc(sizeof(double)*vw*(cwidth-1)),malloc(sizeof(double)*vh*(cheight-1))};

	switch(basis) {
		case INTERPOLATED: {
			for(size_t t1 = 0; t1 < vw; t1++)
				for(size_t t2 = 1; t2 < cwidth; t2++)
					twiddles[0][t1*(cwidth-1)+t2-1] = cos((t1*scale_den/scale_num+vx+0.5L) * t2 * M_PIl / width);
			for(size_t t1 = 0; t1 < vh; t1++)
				for(int t2 = 1; t2 < cheight; t2++)
					twiddles[1][t1*(cheight-1)+t2-1] = cos((t1*scale_den/scale_num+vy+0.5L) * t2 * M_PIl / height);
		}; break;
		case CENTERED: {
			for(size_t t1 = 0; t1 < vw; t1++)
				for(size_t t2 = 1; t2 < cwidth; t2++)
					twiddles[0][t1*(cwidth-1)+t2-1] = cos((t1*(width-1)*scale_den/(scale_num*width-scale_den)+vx+0.5L) * t2 * M_PIl / width);
			for(size_t t1 = 0; t1 < vh; t1++)
				for(int t2 = 1; t2 < cheight; t2++)
					twiddles[1][t1*(cheight-1)+t2-1] = cos((t1*(height-1)*scale_den/(scale_num*width-scale_den)+vy+0.5L) * t2 * M_PIl / height);
		}; break;<commit_msg>Fix centered interpolation when height != width<commit_after>/*
 * zoom - Interpolate images with a cosine basis at arbitrary scales/offsets.
 * Copyright 2013-2016 <EMAIL>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <wand/MagickWand.h>
#include <getopt.h>

#include <fftw3.h>

#include "longmath.h"

enum basis {
	INTERPOLATED = 0,
	CENTERED,
	NATIVE,
	UNITARY
};

void usage(const char* self) {
	printf("usage: %s -s scale -p pos -v viewport --basis=interpolated,centered,native,unitary -c --showsamples=1(point),2(grid) input output\n",self);
	exit(0);
}

int main(int argc, char* argv[]) {
	long double vx = 0, vy = 0;
	size_t vw = 0, vh = 0;
	bool vflag = false, centered = false;
	int showsamples = 0;
	long double scale_num = 1;
	unsigned long long scale_den = 1;
	int basis = INTERPOLATED;
	int c;
	const struct option opts[] = {
		{"showsamples",optional_argument,NULL,1},
		{"basis",required_argument,NULL,2},
		{0}
	};

	while((c = getopt_long(argc,argv,"s:v:p:c",opts,&optind)) != -1) {
		switch(c) {
			case  0 : break;
			case 's': sscanf(optarg,"%Lf/%llu",&scale_num,&scale_den); break;
			case 'v': sscanf(optarg,"%zux%zu",&vw,&vh); break;
			case 'p': sscanf(optarg,"%Lfx%Lf",&vx,&vy); break;
			case 'c': centered = true; break;
			case 1: showsamples = strtol(optarg,NULL,10); break;
			case 2: {
				if(!strcmp(optarg,"centered"))
					basis = CENTERED;
				else if(!strcmp(optarg,"native"))
					basis = NATIVE;
				else if(!strcmp(optarg,"unitary"))
					basis = UNITARY;
			}; break;
			default: usage(argv[0]);
		}
	}

	if(argc-optind < 2)
		usage(argv[0]);

	const char* infile = argv[optind++],* outfile = argv[optind++];

	MagickWandGenesis();
	MagickWand* wand = NewMagickWand();
	if(MagickReadImage(wand,infile) == MagickFalse) {
		DestroyMagickWand(wand);
		MagickWandTerminus();
		return 1;
	}
	size_t width = MagickGetImageWidth(wand), height = MagickGetImageHeight(wand);
	if(!vw) vw = width*scale_num/scale_den;
	if(!vh) vh = height*scale_num/scale_den;

	double* coeffs = malloc(sizeof(double)*width*height*3);
	MagickExportImagePixels(wand,0,0,width,height,"RGB",DoublePixel,coeffs);

	if(centered) {
		vx = vx*scale_num/scale_den - vw/2.L;
		vy = vy*scale_num/scale_den - vh/2.L;
	}
	long double scale = scale_num / scale_den;
	size_t nwidth = round(width * scale_num / scale_den), nheight = round(height * scale_num / scale_den);
	size_t cwidth = nwidth < width ? nwidth : width, cheight = nheight < height ? nheight : height;
	unsigned char* icoeffs = malloc(vw*vh*3);
	double* tmp = malloc(sizeof(double)*cheight);
	double* twiddles[2] = {malloc(sizeof(double)*vw*(cwidth-1)),malloc(sizeof(double)*vh*(cheight-1))};

	switch(basis) {
		case INTERPOLATED: {
			for(size_t t1 = 0; t1 < vw; t1++)
				for(size_t t2 = 1; t2 < cwidth; t2++)
					twiddles[0][t1*(cwidth-1)+t2-1] = cos((t1*scale_den/scale_num+vx+0.5L) * t2 * M_PIl / width);
			for(size_t t1 = 0; t1 < vh; t1++)
				for(int t2 = 1; t2 < cheight; t2++)
					twiddles[1][t1*(cheight-1)+t2-1] = cos((t1*scale_den/scale_num+vy+0.5L) * t2 * M_PIl / height);
		}; break;
		case CENTERED: {
			for(size_t t1 = 0; t1 < vw; t1++)
				for(size_t t2 = 1; t2 < cwidth; t2++)
					twiddles[0][t1*(cwidth-1)+t2-1] = cos((t1*(width-1)*scale_den/(scale_num*width-scale_den)+vx+0.5L) * t2 * M_PIl / width);
			for(size_t t1 = 0; t1 < vh; t1++)
				for(int t2 = 1; t2 < cheight; t2++)
					twiddles[1][t1*(cheight-1)+t2-1] = cos((t1*(height-1)*scale_den/(scale_num*height-scale_den)+vy+0.5L) * t2 * M_PIl / height);
		}; break;
{'fraction_non_alphanumeric': 0.18070766638584668, 'fraction_numerical': 0.031873069362538614, 'mean_word_length': 4.339580209895052, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5722359', 'n_tokens_mistral': 3276, 'n_tokens_neox': 2995, 'n_words': 600}