1 /*
2 * This file is part of the Scale2x project.
3 *
4 * Copyright (C) 2003 Andrea Mazzoleni
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*
22 * This is the source of a simple command line tool which uses the fast
23 * implementation of the Scale effects.
24 *
25 * You can find an high level description of the effects at :
26 *
27 * http://scale2x.sourceforge.net/
28 */
29
30 #include "scalebit.h"
31 #include "file.h"
32 #include "portable.h"
33
34 #include <zlib.h>
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39
file_process(const char * file0,const char * file1,int opt_scale_x,int opt_scale_y,int opt_crc)40 int file_process(const char* file0, const char* file1, int opt_scale_x, int opt_scale_y, int opt_crc)
41 {
42 unsigned pixel;
43 unsigned width;
44 unsigned height;
45 unsigned char* src_ptr;
46 unsigned src_slice;
47 unsigned char* dst_ptr;
48 unsigned dst_slice;
49 int type;
50 int channel;
51 png_color* palette;
52 unsigned palette_size;
53
54 if (file_read(file0, &src_ptr, &src_slice, &pixel, &width, &height, &type, &channel, &palette, &palette_size, 1) != 0) {
55 goto err;
56 }
57
58 if (scale_precondition(opt_scale_x * 100 + opt_scale_y, pixel, width, height) != 0) {
59 fprintf(stderr, "Error in the size of the source bitmap. Generally this happen\n");
60 fprintf(stderr, "when the bitmap is too small or when the width is not an exact\n");
61 fprintf(stderr, "multiplier of 8 bytes.\n");
62 goto err_src;
63 }
64
65 dst_slice = width * pixel * opt_scale_x;
66 dst_ptr = malloc(dst_slice * height * opt_scale_y);
67 if (!dst_ptr) {
68 fprintf(stderr, "Low memory.\n");
69 goto err_src;
70 }
71
72 scale(opt_scale_x * 100 + opt_scale_y, dst_ptr, dst_slice, src_ptr, src_slice, pixel, width, height);
73
74 if (file_write(file1, dst_ptr, dst_slice, pixel, width * opt_scale_x, height * opt_scale_y, type, channel, palette, palette_size) != 0) {
75 goto err_dst;
76 }
77
78 if (opt_crc) {
79 unsigned crc = crc32(0, dst_ptr, dst_slice * height * opt_scale_y);
80 printf("%08x\n", crc);
81 }
82
83 free(dst_ptr);
84 free(src_ptr);
85 free(palette);
86
87 return 0;
88
89 err_dst:
90 free(dst_ptr);
91 err_src:
92 free(src_ptr);
93 free(palette);
94 err:
95 return -1;
96 }
97
version(void)98 void version(void) {
99 printf(PACKAGE " v" VERSION " by Andrea Mazzoleni\n");
100 }
101
usage(void)102 void usage(void) {
103 version();
104 printf("Fast implementation of the Scale2/3/4x effects\n");
105 #if defined(__GNUC__) && (defined(HAVE_MMX) || defined(__amd64__))
106 printf("(using Pentium MMX optimization)\n");
107 #endif
108 printf("\nSyntax: scalex [-k N] FROM.png TO.png\n");
109 printf("\nOptions:\n");
110 printf("\t-k N\tSelect the scale factor. 2, 2x3, 2x4, 3 or 4. (default 2).\n");
111 printf("\nMore info at http://scale2x.sourceforge.net/\n");
112 exit(EXIT_FAILURE);
113 }
114
115 #ifdef HAVE_GETOPT_LONG
116 struct option long_options[] = {
117 {"scale", 1, 0, 'k'},
118 {"crc", 0, 0, 'c'},
119 {"help", 0, 0, 'h'},
120 {"version", 0, 0, 'v'},
121 {0, 0, 0, 0}
122 };
123 #endif
124
125 #define OPTIONS "k:chv"
126
main(int argc,char * argv[])127 int main(int argc, char* argv[]) {
128 int opt_scale_x = 2;
129 int opt_scale_y = 2;
130 int opt_crc = 0;
131 int c;
132
133 opterr = 0;
134
135 while ((c =
136 #ifdef HAVE_GETOPT_LONG
137 getopt_long(argc, argv, OPTIONS, long_options, 0))
138 #else
139 getopt(argc, argv, OPTIONS))
140 #endif
141 != EOF) {
142 switch (c) {
143 case 'h' :
144 usage();
145 exit(EXIT_SUCCESS);
146 case 'v' :
147 version();
148 exit(EXIT_SUCCESS);
149 case 'k' :
150 if (strcmp(optarg, "2") == 0) {
151 opt_scale_x = 2;
152 opt_scale_y = 2;
153 } else if (strcmp(optarg, "3") == 0) {
154 opt_scale_x = 3;
155 opt_scale_y = 3;
156 } else if (strcmp(optarg, "4") == 0) {
157 opt_scale_x = 4;
158 opt_scale_y = 4;
159 } else {
160 if (sscanf(optarg, "%dx%d", &opt_scale_x, &opt_scale_y) != 2
161 || opt_scale_x < 1
162 || opt_scale_y < 1
163 ) {
164 printf("Invalid -k option. Valid values are 2, 2x3, 2x4, 3 and 4.\n");
165 exit(EXIT_FAILURE);
166 }
167 }
168 break;
169 case 'c' :
170 opt_crc = 1;
171 break;
172 default:
173 printf("Unknown option `%c'.\n", (char)optopt);
174 exit(EXIT_FAILURE);
175 }
176 }
177
178 if (optind + 2 != argc) {
179 usage();
180 exit(EXIT_FAILURE);
181 }
182
183 if (file_process(argv[optind], argv[optind+1], opt_scale_x, opt_scale_y, opt_crc) != 0) {
184 exit(EXIT_FAILURE);
185 }
186
187 return EXIT_SUCCESS;
188 }
189
190