PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Pristine-Pro/CONVERT/SCALE.C

http://github.com/AnimatorPro/Animator-Pro
C | 790 lines | 663 code | 58 blank | 69 comment | 124 complexity | afa294cceb5e5b9eb439bc4854783277 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* scale.c - routines to do pixel averaging/interpolation image scaling. */
  2. #include "errcodes.h"
  3. #include "convert.h"
  4. #include "scale.h"
  5. #include "ffile.h"
  6. #include "rgbcmap.h"
  7. #include "reqlib.h"
  8. #include "softmenu.h"
  9. #define WHOLESCALE 256
  10. FILE *rgb_files[3];
  11. char *rgb_names[3] =
  12. /* files for each of the red/green/blue components */
  13. {
  14. "=:red",
  15. "=:green",
  16. "=:blue",
  17. };
  18. Errcode rgb_temp_err(Errcode err)
  19. {
  20. return(softerr(err, "rgb_temp"));
  21. }
  22. void kill_rgb_files()
  23. {
  24. int i;
  25. for (i=0;i<3;i++)
  26. pj_delete(rgb_names[i]);
  27. }
  28. Errcode open_rgb_files(char *mode, int comp_count)
  29. {
  30. Errcode err;
  31. int i;
  32. for (i=0; i<comp_count; i++)
  33. {
  34. if ((err = ffopen(rgb_names[i], &rgb_files[i], mode)) < Success)
  35. {
  36. close_rgb_files();
  37. break;
  38. }
  39. }
  40. return(rgb_temp_err(err));
  41. }
  42. close_rgb_files()
  43. {
  44. int i;
  45. for (i=0; i<3; i++)
  46. ffclose(&rgb_files[i]);
  47. }
  48. Errcode abort_scale()
  49. /*****************************************************************************
  50. * Query abuser if they wanna abort the ardous scaling process
  51. ****************************************************************************/
  52. {
  53. return(soft_abort("scale_abort"));
  54. }
  55. void pix_ave_scale(UBYTE *s, int sct, UBYTE *d, int dct)
  56. /*****************************************************************************
  57. * Do a pixel averaging/interpolation scale of s into d.
  58. ****************************************************************************/
  59. {
  60. if (sct > dct) /* going to do some averaging */
  61. {
  62. int i;
  63. int j, jend, lj;
  64. long lasts, ldiv;
  65. long acc, div;
  66. long t1,t2;
  67. ldiv = WHOLESCALE;
  68. lasts = s[0];
  69. lj = 0;
  70. for (i=0; i<dct; i++)
  71. {
  72. acc = lasts*ldiv;
  73. div = ldiv;
  74. t1 = (i+1)*(long)sct;
  75. jend = t1/dct;
  76. for (j = lj+1; j<jend; j++)
  77. {
  78. acc += s[j]*WHOLESCALE;
  79. div += WHOLESCALE;
  80. }
  81. t2 = t1 - jend*(long)dct;
  82. lj = jend;
  83. lasts = s[lj];
  84. if (t2 == 0)
  85. {
  86. ldiv = WHOLESCALE;
  87. }
  88. else
  89. {
  90. ldiv = WHOLESCALE*t2/dct;
  91. div += ldiv;
  92. acc += lasts*ldiv;
  93. ldiv = WHOLESCALE-ldiv;
  94. }
  95. *d++ = acc/div;
  96. }
  97. }
  98. else if (dct == sct) /* they's the same */
  99. {
  100. while (--dct >= 0)
  101. *d++ = *s++;
  102. }
  103. else if (sct == 1)
  104. {
  105. while (--dct >= 0)
  106. *d++ = *s;
  107. }
  108. else/* going to do some interpolation */
  109. {
  110. int i;
  111. long t1;
  112. long p1;
  113. long err;
  114. int dct2;
  115. dct -= 1;
  116. sct -= 1;
  117. dct2 = dct/2;
  118. t1 = 0;
  119. for (i=0; i<=dct; i++)
  120. {
  121. p1 = t1/dct;
  122. err = t1 - p1*dct;
  123. if (err == 0)
  124. *d++ = s[p1];
  125. else
  126. *d++ = (s[p1]*(dct-err)+s[p1+1]*err+dct2)/dct;
  127. t1 += sct;
  128. }
  129. }
  130. }
  131. static void vga_to_red(UBYTE *in, UBYTE *out, int w, UBYTE *cmap)
  132. /*****************************************************************************
  133. * Take a pixel buffer as input and run it through one of the components
  134. * of cmap (organized as RGB triples.)
  135. ****************************************************************************/
  136. {
  137. while (--w >= 0)
  138. *out++ = cmap[3 * *in++];
  139. }
  140. static Errcode scale_xdim_cel(Rcel *cel, int new_w, int comp_count)
  141. /*****************************************************************************
  142. * Take a color mapped cel and write it's RGB components into files,
  143. * scaling as you go.
  144. ****************************************************************************/
  145. {
  146. Errcode err = Success;
  147. UBYTE *line_in = NULL;
  148. UBYTE *rgb_in = NULL;
  149. UBYTE *rgb_out = NULL;
  150. UBYTE *cmap = (UBYTE *)(cel->cmap->ctab);
  151. int w = cel->width;
  152. int h = cel->height;
  153. int i,j;
  154. int saymod = 0;
  155. if ((err = open_rgb_files("wb", comp_count)) < Success)
  156. goto OUT;
  157. if ((rgb_in = pj_malloc(w)) == NULL
  158. || (rgb_out = pj_malloc(new_w)) == NULL
  159. || (line_in = pj_malloc(w)) == NULL)
  160. {
  161. err = Err_no_memory;
  162. goto OUT;
  163. }
  164. rdisk_set_max_to_avail(); /* set to max ram available */
  165. for (j=0; j<h; j++)
  166. {
  167. if (--saymod <= 0)
  168. {
  169. if ((err = abort_scale()) < Success)
  170. goto OUT;
  171. soft_status_line("!%d%d","ctop_xscline",j,h);
  172. saymod = 25;
  173. }
  174. pj_get_hseg(cel,line_in,0,j,w);
  175. for (i=0; i<comp_count; i++)
  176. {
  177. vga_to_red(line_in, rgb_in, w, cmap+i);
  178. pix_ave_scale(rgb_in, w, rgb_out, new_w);
  179. if ((err = ffwrite(rgb_files[i],rgb_out,new_w)) < Success)
  180. goto OUT;
  181. }
  182. }
  183. OUT:
  184. pj_freez(&rgb_in);
  185. pj_freez(&rgb_out);
  186. pj_freez(&line_in);
  187. close_rgb_files();
  188. return(rgb_temp_err(err));
  189. }
  190. static void get_column(UBYTE *s, UBYTE *d, int w, int h)
  191. /*****************************************************************************
  192. * Get a column d from a 2-D array of pixels s.
  193. ****************************************************************************/
  194. {
  195. while (--h >= 0)
  196. {
  197. *d++ = *s;
  198. s += w;
  199. }
  200. }
  201. static void put_column(UBYTE *s, UBYTE *d, int w, int h)
  202. /*****************************************************************************
  203. * Put s into a column of a 2-D array of pixels in d.
  204. ****************************************************************************/
  205. {
  206. while (--h >= 0)
  207. {
  208. *d = *s++;
  209. d += w;
  210. }
  211. }
  212. static Errcode scaley(
  213. UBYTE *inbytes, /* unscaled source 2-d array */
  214. UBYTE *outbytes, /* scaled destination 2-d array */
  215. UBYTE *inline, /* line buffer size oh */
  216. UBYTE *outline, /* line buffer size nh */
  217. int w, /* width of source and destination */
  218. int oh, /* height of source */
  219. int nh, /* height of destination */
  220. char *comp_name) /* name of color component we're scaling */
  221. /*****************************************************************************
  222. * interpolate scale a byte-plane in memory in y dimension
  223. ****************************************************************************/
  224. {
  225. int i;
  226. char buf[50];
  227. int saymod = 0;
  228. Errcode err = Success;
  229. for (i=0; i<w; i++)
  230. {
  231. get_column(inbytes++, inline, w, oh);
  232. pix_ave_scale(inline, oh, outline, nh);
  233. put_column(outline, outbytes++, w, nh);
  234. if (--saymod <= 0)
  235. {
  236. if ((err = abort_scale()) < Success)
  237. goto OUT;
  238. soft_status_line("!%s%d%d", "ctop_yscline", comp_name,i,w);
  239. saymod = 50;
  240. }
  241. }
  242. OUT:
  243. return(err);
  244. }
  245. Errcode yscale_file(char *name, int w, int oh, int nh)
  246. /*****************************************************************************
  247. * Assuming name is a file that contains an array of w*oh pixels,
  248. * scale file so it contains an array of w*nh pixels.
  249. ****************************************************************************/
  250. {
  251. Errcode err = Success;
  252. UBYTE *inbytes = NULL;
  253. UBYTE *outbytes;
  254. Rcel *outcel = NULL;
  255. long ibsize = w*oh; /* size of input file */
  256. UBYTE *inline = NULL, *outline = NULL; /* Line buffers */
  257. if (oh == nh) /* if input and output size same done already */
  258. return(Success);
  259. ibsize = w * oh; /* calculate size of input file */
  260. if ((inbytes = pj_malloc(ibsize)) == NULL
  261. || (inline = pj_malloc(oh)) == NULL
  262. || (outline = pj_malloc(nh)) == NULL)
  263. {
  264. err = Err_no_memory;
  265. goto OUT;
  266. }
  267. if ((err = valloc_ramcel(&outcel, w, nh)) < Success)
  268. goto OUT;
  269. outbytes = outcel->hw.bm.bp[0];
  270. if ((err = read_gulp(name, inbytes, ibsize)) < Success)
  271. goto OUT;
  272. if ((err = scaley(inbytes, outbytes, inline, outline, w, oh, nh, name))
  273. < Success)
  274. goto OUT;
  275. if ((err = write_gulp(name, outbytes, w*nh)) < Success)
  276. goto OUT;
  277. grey_cmap(outcel->cmap);
  278. conv_see_cel(outcel);
  279. OUT:
  280. pj_gentle_free(outline);
  281. pj_gentle_free(inline);
  282. pj_gentle_free(inbytes);
  283. freez_cel(&outcel);
  284. return(err);
  285. }
  286. void cc_fit_line(Ccache *cc, Cmap *cmap, UBYTE **rgb_bufs, UBYTE *dest, int count)
  287. /*****************************************************************************
  288. * Synthesize dest from rgb components using ccache.
  289. ****************************************************************************/
  290. {
  291. UBYTE *r = *rgb_bufs++;
  292. UBYTE *g = *rgb_bufs++;
  293. UBYTE *b = *rgb_bufs;
  294. Rgb3 rgb;
  295. while (--count >= 0)
  296. {
  297. rgb.r = *r++;
  298. rgb.g = *g++;
  299. rgb.b = *b++;
  300. *dest++ = cc_closest(cc, &rgb, cmap, cs.do_dither);
  301. }
  302. }
  303. Errcode cmap_from_rgb_files(Cmap *cmap, int w, int h, int comp_count)
  304. /*****************************************************************************
  305. * Make up a color map based on contents of RGB files.
  306. ****************************************************************************/
  307. {
  308. Errcode err;
  309. int j;
  310. UBYTE *histogram = NULL;
  311. UBYTE *rgbs[3] = {NULL, NULL, NULL};
  312. if (comp_count == 1) /* deal with the all grey case quickly */
  313. {
  314. grey_cmap(cmap);
  315. return(Success);
  316. }
  317. if ((err = alloc_histogram(&histogram)) < Success)
  318. goto OUT;
  319. if ((err = open_rgb_files("rb", comp_count)) < Success)
  320. goto OUT;
  321. j = 3;
  322. while (--j >= 0)
  323. {
  324. if ((rgbs[j] = pj_malloc(w)) == NULL)
  325. {
  326. err = Err_no_memory;
  327. goto OUT;
  328. }
  329. }
  330. soft_status_line("ctop_hist");
  331. while (--h >= 0)
  332. {
  333. j = 3;
  334. while (--j >= 0) /* read in a line of each component */
  335. {
  336. if ((err = ffread(rgb_files[j], rgbs[j], w)) < Success)
  337. goto OUT;
  338. }
  339. hist_set_bits(histogram, rgbs, w);
  340. }
  341. hist_to_cmap(&histogram, cmap);
  342. OUT:
  343. close_rgb_files();
  344. freez_histogram(&histogram);
  345. pj_gentle_free(rgbs[0]);
  346. pj_gentle_free(rgbs[1]);
  347. pj_gentle_free(rgbs[2]);
  348. return(err);
  349. }
  350. Errcode rgb_files_to_cel(Rcel *cel, int comp_count, Boolean new_cmap,
  351. Boolean flip)
  352. /*****************************************************************************
  353. * Read color component files into the cel color fitting to the cel's
  354. * cmap.
  355. ****************************************************************************/
  356. {
  357. Errcode err;
  358. int w = cel->width;
  359. int h = cel->height;
  360. Cmap *cmap = cel->cmap;
  361. Ccache *cc = NULL;
  362. UBYTE *rgb_bufs[3];
  363. UBYTE *lbuf = NULL;
  364. int i,j;
  365. int saymod = 0;
  366. int y,dy;
  367. rgb_bufs[0] = rgb_bufs[1] = rgb_bufs[2] = NULL; /* for error recovery */
  368. if (new_cmap)
  369. {
  370. if ((err = cmap_from_rgb_files(cmap, w, h, comp_count)) < Success)
  371. goto OUT;
  372. }
  373. if ((err = open_rgb_files("rb", comp_count)) < Success)
  374. goto OUT;
  375. /* Allocate line buffers */
  376. if ((lbuf = pj_malloc(w)) == NULL)
  377. {
  378. err = Err_no_memory;
  379. goto OUT;
  380. }
  381. for (i=0; i<comp_count; ++i)
  382. {
  383. if ((rgb_bufs[i] = pj_malloc(w)) == NULL)
  384. {
  385. err = Err_no_memory;
  386. goto OUT;
  387. }
  388. }
  389. if (comp_count == 1)
  390. rgb_bufs[1] = rgb_bufs[2] = rgb_bufs[0];
  391. if ((err = cc_make(&cc, comp_count==1, cs.colors_256)) < Success)
  392. goto OUT;
  393. if (flip)
  394. {
  395. y = h-1;
  396. dy = -1;
  397. }
  398. else
  399. {
  400. y = 0;
  401. dy = 1;
  402. }
  403. for (i=0; i<h; ++i)
  404. {
  405. if (--saymod <= 0)
  406. {
  407. if ((err = abort_scale()) < Success)
  408. goto OUT;
  409. soft_status_line("!%d%d","ctop_cfitline",i,h);
  410. saymod = 10;
  411. }
  412. for (j=0; j<comp_count; ++j)
  413. {
  414. if ((err = ffread(rgb_files[j],rgb_bufs[j],w)) < Success)
  415. goto OUT;
  416. }
  417. cc_fit_line(cc,cmap,rgb_bufs,lbuf,w);
  418. pj_put_hseg(cel, lbuf, 0, y, w);
  419. y += dy;
  420. }
  421. OUT:
  422. cc_free(cc);
  423. for (i=0; i<comp_count; ++i)
  424. pj_gentle_free(rgb_bufs[i]);
  425. pj_gentle_free(lbuf);
  426. close_rgb_files();
  427. return(err);
  428. }
  429. static Errcode pcel_from_rgb_files(Rcel **pcel, int w, int h, Cmap *cmap,
  430. int comp_count)
  431. /*****************************************************************************
  432. * Make up an Rcel wxh from the rgb files fitting them to the color map.
  433. ****************************************************************************/
  434. {
  435. Errcode err = Success;
  436. Rcel *cel;
  437. if ((err = valloc_anycel(&cel, w, h)) < Success)
  438. return(err);
  439. pj_cmap_copy(cmap, cel->cmap);
  440. if ((err = rgb_files_to_cel(cel, comp_count,cs.recalc_colors,FALSE)) < Success)
  441. freez_cel(&cel);
  442. *pcel = cel;
  443. return(err);
  444. }
  445. static Boolean is_grey_cel(Rcel *cel)
  446. /*****************************************************************************
  447. * Return TRUE if all pixels in Cel are a shade of grey.
  448. ****************************************************************************/
  449. {
  450. UBYTE cused[COLORS]; /* Table of colors used */
  451. int i = COLORS;
  452. Rgb3 *ct = cel->cmap->ctab;
  453. UBYTE *cu = cused;
  454. UBYTE r;
  455. make_cused(cel, cused, COLORS);
  456. while (--i >= 0)
  457. {
  458. if (*cu++)
  459. {
  460. r = ct->r;
  461. if (r != ct->g || r != ct->b)
  462. return(FALSE);
  463. }
  464. ++ct;
  465. }
  466. return(TRUE);
  467. }
  468. static Errcode cel_to_scaled_rgb(Rcel *cel, int neww, int newh,
  469. int *pcomp_count)
  470. /*****************************************************************************
  471. * Take a cel and transform it into scaled rgb files.
  472. ****************************************************************************/
  473. {
  474. Errcode err;
  475. int i;
  476. int comp_count = (is_grey_cel(cel) ? 1 : 3);
  477. if ((err = scale_xdim_cel(cel, neww, comp_count)) < Success)
  478. goto OUT;
  479. for (i=0; i<comp_count; ++i)
  480. {
  481. soft_status_line("!%d", "ctop_yscale", i);
  482. if ((err = yscale_file(rgb_names[i],neww,
  483. cel->height,newh)) < Success)
  484. goto OUT;
  485. }
  486. OUT:
  487. *pcomp_count = comp_count;
  488. return(err);
  489. }
  490. static Errcode scale_in_place(Rcel **pcel, int neww, int newh)
  491. /*****************************************************************************
  492. * This one scales a single frame cel, replacing the old cel with
  493. * the new scaled one.
  494. ****************************************************************************/
  495. {
  496. Errcode err;
  497. Rcel *cel = *pcel;
  498. Cmap *cmap = NULL;
  499. int comp_count;
  500. /* clone cmap for future reference */
  501. if((err = pj_cmap_alloc(&cmap,COLORS)) < Success)
  502. goto ERROR;
  503. pj_cmap_copy(cel->cmap, cmap);
  504. if ((err = cel_to_scaled_rgb(cel, neww, newh, &comp_count)) < Success)
  505. goto ERROR;
  506. freez_cel(pcel); /* get rid of old cel */
  507. err = pcel_from_rgb_files(pcel,neww, newh, cmap, comp_count);
  508. ERROR:
  509. pj_cmap_free(cmap);
  510. kill_rgb_files();
  511. return(err);
  512. }
  513. static Errcode scale_copy_cel(Rcel *source, Rcel *dest)
  514. /*****************************************************************************
  515. * Scale source cel into dest.
  516. ****************************************************************************/
  517. {
  518. Errcode err = Success;
  519. int comp_count;
  520. if ((err = cel_to_scaled_rgb(source, dest->width, dest->height, &comp_count))
  521. < Success)
  522. goto OUT;
  523. pj_cmap_copy(source->cmap, dest->cmap);
  524. if ((err = rgb_files_to_cel(dest,comp_count,cs.recalc_colors,FALSE)) < Success)
  525. goto OUT;
  526. OUT:
  527. kill_rgb_files();
  528. return(err);
  529. }
  530. typedef struct
  531. {
  532. Rcel *cel;
  533. } Scale_data;
  534. static Errcode scale_seek(int ix, void *data)
  535. /*****************************************************************************
  536. * Called from a PDR save routine. This moves the main convert frame
  537. * to the input index, and then makes a scaled copy of it in the data
  538. * frame. Also keeps user informed of progress a bit by updating the
  539. * wait box with the frame count and displaying scaled cel.
  540. ****************************************************************************/
  541. {
  542. #define sd ((Scale_data *)data)
  543. Errcode err;
  544. if ((err = soft_abort("conv_abort")) < Success)
  545. goto OUT;
  546. soft_put_wait_box("!%d%d", "ctop_scalef", ix+1, cs.ifi.ai.num_frames);
  547. if ((err = ifi_cel_seek(ix,NULL)) < Success)
  548. goto OUT;
  549. if ((err = scale_copy_cel(cs.ifi.cel, sd->cel)) < Success)
  550. goto OUT;
  551. conv_see_cel(sd->cel);
  552. OUT:
  553. return(err);
  554. #undef sd
  555. }
  556. Errcode scale_flic(char *sname, int nw, int nh, char *pdr_name)
  557. {
  558. Errcode err = Success;
  559. Rcel *cur_frame = NULL;
  560. Rcel *prev_frame = NULL;
  561. Anim_info ai;
  562. Pdr *pdr;
  563. Image_file *ifile = NULL;
  564. Scale_data sd;
  565. if ((err = get_new_pdr(&pdr, pdr_name)) < Success)
  566. goto OUT;
  567. ai = cs.ifi.ai;
  568. ai.width = nw;
  569. ai.height = nh;
  570. if ((err = pdr_create_ifile(pdr, sname, &ifile, &ai)) < Success)
  571. goto OUT;
  572. if ((err = valloc_ramcel(&cur_frame, nw, nh)) < Success)
  573. goto OUT;
  574. if ((err = valloc_ramcel(&prev_frame, nw, nh)) < Success)
  575. goto OUT;
  576. sd.cel = cur_frame;
  577. if ((err = scale_seek(0,&sd)) < Success)
  578. goto OUT;
  579. if ((err = pdr_save_frames(ifile, cur_frame,ai.num_frames,scale_seek,
  580. &sd,prev_frame)) < Success)
  581. {
  582. pdr_close_ifile(&ifile);
  583. pj_delete(sname); /* on error delete bogus file */
  584. goto OUT;
  585. }
  586. OUT:
  587. pdr_close_ifile(&ifile);
  588. conv_free_pdr(&pdr);
  589. freez_cel(&cur_frame);
  590. freez_cel(&prev_frame);
  591. return(err);
  592. }
  593. static Errcode render_scale()
  594. {
  595. Errcode err;
  596. char *name;
  597. char *pdr_name;
  598. char *suffi;
  599. char titbuf[80];
  600. char nbuf[32];
  601. if (cs.ifi.ai.num_frames == 1) /* single frame scale */
  602. {
  603. err = scale_in_place(&cs.ifi.cel, cs.scalew, cs.scaleh);
  604. conv_center_cel(cs.ifi.cel);
  605. }
  606. else
  607. {
  608. pdr_name = fli_pdr_name;
  609. suffi = ".FLC";
  610. /* If 320x200 see if they want it to be lo res animator
  611. * compatible */
  612. if (cs.scalew == 320 && cs.scaleh == 200)
  613. if (soft_yes_no_box("conv_scale_flilo"))
  614. {
  615. pdr_name = flilores_pdr_name;
  616. suffi = ".FLI";
  617. }
  618. if ((name = conv_save_name(stack_string("conv_sclname", titbuf),
  619. suffi, stack_string("conv_sclword",nbuf))) != NULL)
  620. {
  621. if ((err = scale_flic(name, cs.scalew, cs.scaleh, pdr_name)) >=
  622. Success)
  623. {
  624. /* Make scaled flic the current flic */
  625. err = get_a_flic(fli_pdr_name, name, NULL);
  626. }
  627. }
  628. else
  629. err = Err_abort;
  630. }
  631. conv_see_cel(cs.ifi.cel);
  632. cleanup_toptext();
  633. return(softerr(err,NULL));
  634. }
  635. void qscale_opts()
  636. {
  637. USHORT mdis[5];
  638. for (;;)
  639. {
  640. /* set up asterisks */
  641. clear_mem(mdis, sizeof(mdis));
  642. if (cs.do_dither)
  643. mdis[0] |= QCF_ASTERISK;
  644. if (cs.recalc_colors)
  645. mdis[1] |= QCF_ASTERISK;
  646. if (cs.colors_256)
  647. mdis[3] |= QCF_ASTERISK;
  648. else
  649. mdis[2] |= QCF_ASTERISK;
  650. switch (soft_qchoice(mdis, "conv_scale_opts"))
  651. {
  652. case 0:
  653. cs.do_dither = !cs.do_dither;
  654. break;
  655. case 1:
  656. cs.recalc_colors = !cs.recalc_colors;
  657. break;
  658. case 2:
  659. cs.colors_256 = FALSE;
  660. break;
  661. case 3:
  662. cs.colors_256 = TRUE;
  663. break;
  664. default:
  665. return;
  666. }
  667. }
  668. }
  669. void qscale_menu()
  670. {
  671. int choice;
  672. long r1, r2;
  673. int sw = vb.pencel->width;
  674. int sh = vb.pencel->height;
  675. if (cs.ifi.cel == NULL) /* This should be handled by disable logic soon */
  676. return;
  677. for (;;)
  678. {
  679. choice = soft_qchoice(NULL,
  680. "!%d%d%d%d%d%d%d%d", "conv_scale",
  681. cs.ifi.cel->width, cs.ifi.cel->height,
  682. cs.scalew, cs.scaleh,
  683. sw, sh,
  684. cs.ifi.ai.width, cs.ifi.ai.height);
  685. switch (choice)
  686. {
  687. case 0: /* Set width */
  688. clip_soft_qreq_number(&cs.scalew, 4, 10000, NULL, NULL,
  689. "conv_scale_width");
  690. break;
  691. case 1: /* Set height */
  692. clip_soft_qreq_number(&cs.scaleh, 4, 10000, NULL, NULL,
  693. "conv_scale_height");
  694. break;
  695. case 2: /* Set Default dims */
  696. cs.scalew = sw;
  697. cs.scaleh = sh;
  698. break;
  699. case 3: /* Correct aspect ratio */
  700. r1 = (long)sw*cs.ifi.cel->height;
  701. r2 = (long)sh*cs.ifi.cel->width;
  702. if (r1 > r2) /* need to shrink y */
  703. {
  704. cs.scalew = cs.ifi.cel->width;
  705. cs.scaleh = (long)(cs.ifi.cel->height * r2 / r1);
  706. }
  707. else /* need to shrink x */
  708. {
  709. cs.scalew = (long)(cs.ifi.cel->width * r1 / r2);
  710. cs.scaleh = cs.ifi.cel->height;
  711. }
  712. break;
  713. case 4: /* Revert... */
  714. cs.scalew = cs.ifi.ai.width;
  715. cs.scaleh = cs.ifi.ai.height;
  716. break;
  717. case 5: /* Dither */
  718. qscale_opts();
  719. break;
  720. case 6: /* Render */
  721. if (render_scale() < Success)
  722. /* exit 'cause cel might not
  723. * exist */
  724. goto OUT;
  725. break;
  726. default:
  727. goto OUT;
  728. }
  729. }
  730. OUT:
  731. return;
  732. }