Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2010 Cameron Zemek ( grom@zeminvaders.net)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Lesser General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2.1 of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12.  * Lesser General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17.  */
  18.  
  19. #include <unistd.h>
  20. #include <stdint.h>
  21. #include <stdlib.h>
  22. #include <hqx.h>
  23. #include <IL/il.h>
  24.  
  25. static inline uint32_t swapByteOrder(uint32_t ui)
  26. {
  27.     return (ui >> 24) | ((ui << 8) & 0x00FF0000) | ((ui >> 8) & 0x0000FF00) | (ui << 24);
  28. }
  29.  
  30. int main(int argc, char *argv[])
  31. {
  32.     int opt;
  33.     int scaleBy = 4;
  34.     while ((opt = getopt(argc, argv, "s:")) != -1) {
  35.         switch (opt) {
  36.         case 's':
  37.             scaleBy = atoi(optarg);
  38.             if (scaleBy != 2 && scaleBy != 3 && scaleBy != 4) {
  39.                 fprintf(stderr, "Only scale factors of 2, 3, and 4 are supported.");
  40.                 return 1;
  41.             }
  42.             break;
  43.         default:
  44.             goto error_usage;
  45.         }
  46.     }
  47.  
  48.     if (optind + 2 > argc) {
  49. error_usage:
  50.         fprintf(stderr, "Usage: %s [-s scaleBy] input output\n", argv[0]);
  51.         return 1;
  52.     }
  53.  
  54.     ILuint handle, width, height;
  55.  
  56.     char *szFilenameIn = argv[optind];
  57.     char *szFilenameOut = argv[optind + 1];
  58.  
  59.     ilInit();
  60.     ilEnable(IL_ORIGIN_SET);
  61.     ilGenImages(1, &handle);
  62.     ilBindImage(handle);
  63.  
  64.     // Load image
  65.     ILboolean loaded = ilLoadImage(szFilenameIn);
  66.     if (loaded == IL_FALSE) {
  67.         fprintf(stderr, "ERROR: can't load '%s'\n", szFilenameIn);
  68.         return 1;
  69.     }
  70.     width = ilGetInteger(IL_IMAGE_WIDTH);
  71.     height = ilGetInteger(IL_IMAGE_HEIGHT);
  72.  
  73.     // Allocate memory for image data
  74.     size_t srcSize = width * height * sizeof(uint32_t);
  75.     uint8_t *srcData = (uint8_t *) malloc(srcSize);
  76.     size_t destSize = width * scaleBy * height * scaleBy * sizeof(uint32_t);
  77.     uint8_t *destData = (uint8_t *) malloc(destSize);
  78.  
  79.     // Init srcData from loaded image
  80.     // We want the pixels in BGRA format so that when converting to uint32_t
  81.     // we get a RGB value due to little-endianness.
  82.     ilCopyPixels(0, 0, 0, width, height, 1, IL_BGRA, IL_UNSIGNED_BYTE, srcData);
  83.  
  84.     uint32_t *sp = (uint32_t *) srcData;
  85.     uint32_t *dp = (uint32_t *) destData;
  86.  
  87.     // If big endian we have to swap the byte order to get RGB values
  88.     #ifdef WORDS_BIGENDIAN
  89.     uint32_t *spTemp = sp;
  90.     for (i = 0; i < srcSize >> 2; i++) {
  91.         spTemp[i] = swapByteOrder(spTemp[i]);
  92.     }
  93.     #endif
  94.  
  95.     hqxInit();
  96.     switch (scaleBy) {
  97.     case 2:
  98.         hq2x_32(sp, dp, width, height);
  99.         break;
  100.     case 3:
  101.         hq3x_32(sp, dp, width, height);
  102.         break;
  103.     case 4:
  104.     default:
  105.         hq4x_32(sp, dp, width, height);
  106.         break;
  107.     }
  108.  
  109.     // If big endian we have to swap byte order of destData to get BGRA format
  110.     #ifdef WORDS_BIGENDIAN
  111.     uint32_t *dpTemp = dp;
  112.     for (i = 0; i < destSize >> 2; i++) {
  113.         dpTemp[i] = swapByteOrder(dpTemp[i]);
  114.     }
  115.     #endif
  116.  
  117.     // Copy destData into image
  118.     ilTexImage(width * scaleBy, height * scaleBy, 0, 4, IL_BGRA, IL_UNSIGNED_BYTE, destData);
  119.  
  120.     // Free image data
  121.     free(srcData);
  122.     free(destData);
  123.  
  124.     // Save image
  125.     ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); // No alpha channel
  126.     ilHint(IL_COMPRESSION_HINT, IL_USE_COMPRESSION);
  127.     ilEnable(IL_FILE_OVERWRITE);
  128.     ILboolean saved = ilSaveImage(szFilenameOut);
  129.  
  130.     ilDeleteImages(1, &handle);
  131.  
  132.     if (saved == IL_FALSE) {
  133.         fprintf(stderr, "ERROR: can't save '%s'\n", szFilenameOut);
  134.         return 1;
  135.     }
  136.  
  137.     return 0;
  138. }
  139.