Logo Search packages:      
Sourcecode: aaphoto version File versions  Download package

aaphoto.c

/*-----------------------------------------------------------------------
    This file is part of aaphoto.

    aaPhoto is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    aaPhoto is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------------*/


//#define __UNIX__
//#define __WIN32__
//#define __AROS__
//#define __BMP_ONLY__



// ---------------------------------------------------
// ----------- Auto Adjust Photo ---------------------
// ----------- András Horváth (C) 2006-2010 ----------
// ----------- Hungary, http://log69.com -------------
// ---------------------------------------------------

/*

aaPhoto Changelog:
--------------------
2010/03/16 - aaPhoto v0.36 - bugfix: fix for tmpfile() patches of libjasper and libjpeg (windows platform only)
                             when running more than one instances of aaphoto at a time, they all used the same
                             temporary files and therefore the images became corrupt
                           - bugfix: it doesn't ask for administrative privileges anymore while running in an admin account
                             under vista and windows 7 (windows platform only)
                           - bugfix: the --rotate180 switch didn't turn the middle line in images with odd heights
                           - JPEG format handling entirely rewritten to be able to handle extra parameters in this format
                             separately, now libjpeg is used directly instead of libjasper for reading / writing JPEG images
                             so libjpeg is a new dependency from now on, formerly only libjasper was depended on it
                           - original DPI values of images are restored in BMP, JPEG and PNG formats during conversion
                           - refining program messages
                           - printing the time elapsed in seconds since program start in verbose mode if not zero
                           - printing extra info of bitmap dimension, resolution and color depth in verbose mode
2010/02/25 - aaPhoto v0.35 - bugfix: possible buffer overflows fixed
2010/02/19 - aaPhoto v0.34 - __UNIX__ macro removed from Makefile, not needed anymore
                           - bugfix: static binary update with patches of libjasper and libjpeg
                             1) sleep() function missing on mingw32 platform
                             2) bad implementation of tmpfile() function on windows platform
                                it tries to create temporary files in the root of current directory
                                instead of the system temporary path so that causes failure for unprivileged users
                                who don't have permissions to write there
                           - update: changes in new version of libpng 1.4.0, aaio.c updated as necessary
                                png_check_sig() function replaced with png_sig_cmp()
                                setjmp(png_ptr->jmpbuf) has been deprecated, changed to setjmp(png_jmpbuf(png_ptr))
                                see more at http://www.libpng.org/pub/png/src/libpng-1.2.x-to-1.4.x-summary.txt
2010/01/10 - aaPhoto v0.33 - some changes in documentation
                           - bugfix: unfreed space caused memory leak
                           - bugfix: uninitialized variable caused --resize to misbehave
                           - fix: change of return values in procedures to reflect standard exit codes
                             now it has a sense to run something like "aaphoto image.jpg && echo OK"
                             formerly return codes meant opposite
                           - fix a warning message during compile time, an include was missing
                           - boundary check of fixed size arrays added for safety reasons
                           - the --speed switch removed, it made the code less platform independent and was fussy anyway
                           - error messages printed to stderr instead of stdout from now
                           - more verbose error message on failure of image load
2009/10/18 - aaPhoto v0.32 - new aaRGB v0.60 version update
                           - new --noexif switch added for the ability to save new image without exif info
                           - new --bmp switch added for BMP format output
                           - new -o, --output switch added for alternate directory output
2009/08/23 - aaPhoto v0.31 - bugfix: __BMP_ONLY__ directive fix in source code
                           - bugfix: writing of BMP images could result in corrupt BMP structure
                           - code cleanup in BMP write function
                           - parameters of switches also work with spaces between them
                           - new aaRGB v0.59 version update
2009/02/22 - aaPhoto v0.30 - implementation of PNG format (RGB and Gray images read / write with alpha channel support)
                           - bugfix: reading corrupt exif info in JPEG files could get into an infinite loop
                           - bugfix: length of exif info was determined wrongly
                           - rework of the parameters and switches parsing part
                           - lots of code cleanup
                           - most of the comments in code translated into english
                           - print messages get flushed out with fflush now during process
                           - the --info switch removed
                           - the -o switch removed for saftey reasons, --overwrite still available
                           - the -h switch added for unix compatibility
                           - the -j1 and -j2 switch removed, --jpg and --jp2 still available
                           - the --png switch is now new for PNG output
                           - the -s switch changed from --speed to --silent for compatibility reasons
                           - the --mute switch changed to -s, --silent and --quiet for unix / posix compatibility
                           - the -V, --verbose switch is now new for more detailed output during image process
                           - the --test switch now turns the --autoadjust switch on by default
                     - the -d, --description and -l, --lincense switches removed
                           - new aaRGB v0.58 version update
2008/02/02 - aaPhoto v0.29 - bugfix: colorspace variable was not defined during the load of BMP format
                           - bugfix: BMP format handling fixed for Jpeg conversion
                           - grayscale images can also be used as an input
                           - change: file name buffer increased (for processing files in folders)
                           - Exif metadata information is now restored during conversion in Jpeg images
2007/08/11 - aaPhoto v0.28 - new aaRGB v0.57 version update
                           - bugfix: removing extra slashes from the end of folders
2007/07/04 - aaPhoto v0.27 - new aaRGB v0.56 version update v0.56 with "Apply only on selection" function
2007/05/26 - aaPhoto v0.26 - bugfix: Win32 version crashed during JPEG-2000 conversion
2007/05/19 - aaPhoto v0.25 - expanding functions: Rotate 90, 180, 270, Flip x, Flip y
2007/05/01 - aaPhoto v0.24 - improving timing values
                           - input parameter can be folders too beside files
                           - bitmap info parameter now working with bmp too
                           - simplifying parameter input: no --autoadjust parameter needed from now, default is on
2007/04/03 - aaPhoto v0.23 - new aaRGB v0.55 version update
2007/04/01 - aaPhoto v0.22 - new aaRGB v0.54 version update
2007/03/30 - aaPhoto v0.21 - bmp_only macro created in source code for other platforms
                           - bug fixes
2007/03/29 - aaPhoto v0.20 - new aaRGB v0.53 version update
2007/02/25 - aaPhoto v0.19 - extra information output within image for testing purposes
2007/02/22 - aaPhoto v0.18 - custom code for BMP input/output (helps in testing)
2007/01/24 - aaPhoto v0.17 - JasPer coder implemented for further image formats
2007/01/04 - aaPhoto v0.16 - stable working command-line version for linux enviroment with BMP format support

aaPhoto end of Changelog.

*/




// global constants and variables

const int max_char = 1024;
const int max_file_name_buffer = 4096 * 1024;

int   file_counter;
char *file_name;

unsigned char *file_name_buffer;
long  file_name_counter;
long  file_name_buffer_pointer;

unsigned char *bitmap_buffer;
unsigned long  bitmap_width;
unsigned long  bitmap_height;

double  xdpi;
double  ydpi;
int     udpi;

int   bitmap_format_bmp_clrspc_type;
int   bitmap_format_jpg_clrspc_type;
int   bitmap_format_jpg_file_type;
int   bitmap_format_png_clrspc_type;
int   bitmap_format_png_interlace_type;
int   bitmap_format_png_compression_type;
int   bitmap_format_png_filter_type;


char *exif_buffer;
long  exif_buffer_length;
long  exif_file_length;
int   exif_flag;

int opt_help;
int opt_version;
int opt_autoadjust;
int opt_overwrite;
int opt_jpg;
int opt_jp2;
int opt_png;
int opt_bmp;
int opt_resize;
int opt_resize_percent;
int opt_rotate90;
int opt_rotate180;
int opt_rotate270;
int opt_flipx;
int opt_flipy;
int opt_output;
char opt_output_path [1024]; // make this max_char size
int opt_quality;
int opt_verbose;
int opt_recursive;
int opt_quiet;
int opt_test;
int opt_noexif;

int char_temp_x;
int char_temp_y;

int mytime;


// system dependent file name separation character
#ifdef __WIN32__
      char slsh[] = "\\";
#else
      char slsh[] = "/";
#endif


#ifndef __BMP_ONLY__
#include <jasper/jasper.h>
#include <png.h>
#include <jpeglib.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <dirent.h>
#include <time.h>
//#include <stddir.h>

#include "aaio.c"
#include "aargb.c"
#include "aaresize.c"




void PRINT_VERSION(void){
char *helpinfo[] = {
"Auto Adjust Photo\n"
"Copyright (C) 2006-2010 Andras Horvath\n"
"E-mail: mail@log69.com - suggestions & feedbacks are welcome\n"
"URL: http://log69.com - the official site\n"
"aaPhoto (command-line) version - v0.36\n"
"aaRGB (color-correction engine) version - v0.60\n"
"last update = 16/03/2010\n"
"\n"
#ifndef __BMP_ONLY__
"The following libraries are used by this program:\n"
"libjpeg - IJG JPEG software, http://www.ijg.org/\n"
"libjasper - JasPer software, http://www.ece.uvic.ca/~mdadams/jasper/\n"
"libpng - PNG software, http://www.libpng.org/\n"
"libz - Compression library, http://www.zlib.net/\n"
#endif
#ifdef __BMP_ONLY__
"BMP_ONLY version. Only BMP format is supported here.\n"
#endif
"\n\0"
}; STRING_PRINT(*helpinfo);
}



void PRINT_DESCRIPTION(void){
char *helpinfo[] = {
"[DESCRIPTION]\n"
"Auto Adjust Photo is a tiny command-line image manipulation tool "
"for automatic color correction of photos. "
"It tries to make the picture look better. "
"The program does this by analyzing the input image and then sets the "
"most optimal contrast, gamma, color balance and saturation for it. "
"See more details at http://log69.com\n"
"\n\0"
}; STRING_PRINT(*helpinfo);
}



void PRINT_LICENSE(void){
char *helpinfo[] = {
"[LICENSE]\n"
"This program is free software; you can redistribute it and/or modify "
"it under the terms of the GNU General Public License as published by "
"the Free Software Foundation; either version 3 of the License, or "
"(at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful, "
"but WITHOUT ANY WARRANTY; without even the implied warranty of "
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License "
"along with this program.  If not, see <http://www.gnu.org/licenses/>.\n"
"\n\0"
}; STRING_PRINT(*helpinfo);
}



void PRINT_HELP(void){
char *helpinfo[] = {
"[HELP]\n"
"USAGE: aaphoto [options] [source files]\n"
"The following image types are supported (thanks to libjasper, libjpeg and libpng):\n"
"mif, pnm / pgm / ppm, bmp, ras, jp2, jpc, jpg, pgx, png\n"
"Quality settings can be applied only to jp2, jpc, jpg formats\n"
"The following options are supported:\n"
"    -h   --help          Print this help\n"
"    -v   --version       Print version information\n"
"    -a   --autoadjust    *Auto adjust the colors of the image\n"
"    -o   --output        *Set output directory\n"
"         --overwrite     *Overwrite mode, the original source file is replaced\n"
"         --jpg           *JPEG image output\n"
"         --jp2           *JPEG 2000 image output\n"
"         --png           *PNG image output with alpha channel support\n"
"         --bmp           *BMP image output\n"
"    -r   --resize        *Resize image with given value taking the longer side in % or pixels\n"
"         --rotate90      *Rotate image with 90 degrees clockwise\n"
"         --rotate180     *Rotate image with 180 degrees\n"
"         --rotate270     *Rotate image with 90 degrees counter-clockwise\n"
"         --flipx         *Mirror image horizontally\n"
"         --flipy         *Mirror image vertically\n"
"         --noexif        *Save image without EXIF info\n"
"    -q   --quality       *Set image quality from 1 to 100\n"
"    -s   --silent        Silent mode, no information printed during operation\n"
"         --quiet         ...same as above\n"
"    -V   --verbose       Print verbose information about processing\n"
//"    -R   --recursive     *Process images recursively\n"
"         --test          *Print detailed test information into image\n"
"\n"
"    * marked parameters need input file\n"
"\n"
"EXAMPLES:\n"
"     aaphoto image.jpg\n"
"     aaphoto -a -r600 -q85 *.jpg\n"
"     aaphoto mydir\n"
"     aaphoto -V --resize70% image.png\n"
"     aaphoto --quality60 image.jp2\n"
"\n"
"REMARKS:\n"
"- auto adjust parameter is set by default but only if no other parameters are given\n"
"- _new file name will be generated without --overwrite parameter\n"
"- on directory input every file will be processed in it but not recursively\n"
"- order of parameters does not matter\n"
"- resizing can be set in percentage too\n"
"- resize parameter should be less or equal than original\n"
"- resize uses the best (and slowest) resampling method\n"
"- default jpeg compression quality is 95%\n"
"- EXIF information is restored in jpeg images by default\n"
"\n\0"

}; STRING_PRINT(*helpinfo);
}



int MAIN_RESIZE(void)
{
      // if there is an Alpha channel too beside RGB (clrspc_type says)
      // then we use the alpha flag to indicate it to the resize function
      int alpha_flag = 0;
      if ((bitmap_format_png_clrspc_type == 4) || (bitmap_format_png_clrspc_type == 6)){
            alpha_flag = 1; }

      if (opt_resize){

            unsigned long opr = opt_resize;
            // calculating resize in percentage
            if (opt_resize_percent){
                  if (bitmap_width > bitmap_height) { opr = bitmap_width  * opr / 100; }
                  else                              { opr = bitmap_height * opr / 100; }
            }

            // if the new size is bigger or equal than the original size, then no process is done
            if (!((opr > bitmap_width) && (opr > bitmap_height))){

                  unsigned long new_width, new_height;
                  if (bitmap_width > bitmap_height){
                        new_width = opr;
                        new_height = bitmap_height * opr / bitmap_width;
                  }
                  else{
                        new_width = bitmap_width * opr / bitmap_height;
                        new_height = opr;
                  }

                  if (new_width < 1) new_width = 1;
                  if (new_height < 1) new_height = 1;

                  if (RESIZE(&bitmap_buffer, &bitmap_width, &bitmap_height, new_width, new_height, alpha_flag)){
                        STRING_PRINT("\n"); STRING_PRINTE("error: memory allocation error\n"); return 1; }

            }

//          else {
//                STRING_PRINT("\n"); STRING_PRINTE("error: resize parameter too big, "
//                      "target size should be less or equal than original\n"); return 1; }

      }

      // Rotate and Flip calls
      if (opt_rotate90) { if (ROTATE90(&bitmap_buffer, &bitmap_width, &bitmap_height, alpha_flag))
                  { STRING_PRINT("\n"); STRING_PRINTE("error: memory allocation error\n"); return 1; } }
      if (opt_rotate180) { if (ROTATE180(&bitmap_buffer, &bitmap_width, &bitmap_height, alpha_flag))
                  { STRING_PRINT("\n"); STRING_PRINTE("error: memory allocation error\n"); return 1; } }
      if (opt_rotate270) { if (ROTATE270(&bitmap_buffer, &bitmap_width, &bitmap_height, alpha_flag))
                  { STRING_PRINT("\n"); STRING_PRINTE("error: memory allocation error\n"); return 1; } }
      if (opt_flipx) { if (FLIPX(&bitmap_buffer, &bitmap_width, &bitmap_height, alpha_flag))
                  { STRING_PRINT("\n"); STRING_PRINTE("error: memory allocation error\n"); return 1; } }
      if (opt_flipy) { if (FLIPY(&bitmap_buffer, &bitmap_width, &bitmap_height, alpha_flag))
                  { STRING_PRINT("\n"); STRING_PRINTE("error: memory allocation error\n"); return 1; } }


      return 0;
}




void MAIN_AARGB(void)
{
//    AARGB_NORMAL(bitmap_buffer, bitmap_width, bitmap_height);
      AARGB_MAIN(bitmap_buffer, bitmap_width, bitmap_height, 0, 0, bitmap_width-1, bitmap_height-1, 0, 0, opt_test);
}




int MAIN_RUN(char *file_name)
{
      // we store the unix time here (seconds)
      mytime = time(NULL);

      /* print info */ STRING_PRINTV("verbose mode on\n");

      /* print info */ if (!(opt_verbose)) STRING_PRINT(file_name);
//    /* print info */ STRING_PRINTV(file_name); STRING_PRINTV("\n");
      /* print info */ STRING_PRINTV(file_name); if (opt_verbose) STRING_PRINT("\n");
      /* print info */ STRING_PRINTV("loading\n");

      // try to load image
      int result = 0;
      result = BITMAP_LOAD(file_name);
      switch (result) {
            case  2:
                  STRING_PRINT("\n"); STRING_PRINTE("error: file does not exist\n"); return 1;
                  break;
            case  1:
                  STRING_PRINT("\n"); STRING_PRINTE("error: file cannot be loaded\n"); return 1;
                  break;
      }

      // determine new file name
      char file_name_new [max_char];
      int res;
      res = GET_FILE_NAME_NEW(file_name, file_name_new);
      if (res > 0){
            if (res == 1){
                  // error code 1 for existing file name
                  STRING_PRINT("\n"); \
                  STRING_PRINTE("error: file already exists with the new name "); \
                  STRING_PRINTE(file_name_new); STRING_PRINTE("\n"); return 1; }
            else {
                  // error code 255 for array boundary error
                  STRING_PRINT("\n"); \
                  STRING_PRINTE("error: file name error\n"); return 1; }
      }

      /* print info */ if (!(opt_verbose)) STRING_PRINT(" .");
      if (opt_autoadjust){
            /* print info */ STRING_PRINTV("auto adjusting colors\n");
            MAIN_AARGB();
      }

      /* print info */ if (!(opt_verbose)) STRING_PRINT(" .");
      if ((opt_resize) || (opt_rotate90) || (opt_rotate180) || (opt_rotate270) || (opt_flipx) || (opt_flipy))
            { if (MAIN_RESIZE()) return 1; }

      /* print info */ if (!(opt_verbose)) STRING_PRINT(" .");
      /* print info */ STRING_PRINTV("saving\n");
      if (BITMAP_SAVE(file_name_new)){ STRING_PRINT("\n"); STRING_PRINTE("error: file cannot be saved\n"); return 1; }

      /* print info */ if (!(opt_verbose)) STRING_PRINT(" done\n");
      /* print info */ STRING_PRINTV("done\n");

      return 0;
}




int MAIN_ARGUMENTS_READ(int argc, char **argv)
{
      opt_help = 0;
      opt_version = 0;
      opt_autoadjust = 0;
      opt_overwrite = 0;
      opt_noexif = 0;
      opt_jpg = 0;
      opt_jp2 = 0;
      opt_png = 0;
      opt_bmp = 0;
      opt_resize = 0;
      opt_rotate90 = 0;
      opt_rotate180 = 0;
      opt_rotate270 = 0;
      opt_flipx = 0;
      opt_flipy = 0;
      opt_resize_percent = 0;
      opt_output = 0;
      opt_quality = 0;
      opt_verbose = 0;
      opt_recursive = 0;
      opt_quiet = 0;
      opt_test = 0;

      int result = 0; // we store the result value of the MAIN_RUN function

      int opt_wrong = 1;
      int opt_wrong_total = 0;
      int opt_counter = 0;

      int opt_quality_space_flag = 0;
      int opt_resize_space_flag = 0;
      int opt_output_space_flag = 0;

      if (argc >= 2) {
            argc--;

            char *myarg;
            while (argc--){
                  //printf("%s\n", *argv);

                  opt_wrong = 1;
                  myarg = *argv++;
                  myarg = *argv;

                  if ((myarg[0] == '-') || (opt_quality_space_flag) || (opt_resize_space_flag) || (opt_output_space_flag)) {

                        // checking switches
                        if ((!STRING_COMPARE(myarg, "-h\0")) || (!STRING_COMPARE(myarg, "--help\0"))){
                              opt_wrong = 0; opt_help = 1; }
                        if ((!STRING_COMPARE(myarg, "-v\0")) || (!STRING_COMPARE(myarg, "--version\0"))){
                              opt_wrong = 0; opt_version = 1; }
                        if ((!STRING_COMPARE(myarg, "-a\0")) || (!STRING_COMPARE(myarg, "--autoadjust\0"))){
                              opt_wrong = 0; opt_autoadjust = 1; }
                        if (!STRING_COMPARE(myarg, "--overwrite\0")){
                              opt_wrong = 0; opt_overwrite = 1; }
                        if (!STRING_COMPARE(myarg, "--noexif\0")){
                              opt_wrong = 0; opt_noexif = 1; }
                        if (!STRING_COMPARE(myarg, "--jpg\0")){
                              opt_wrong = 0; opt_jpg = 1; }
                        if (!STRING_COMPARE(myarg, "--jp2\0")){
                              opt_wrong = 0; opt_jp2 = 1; }
                        if (!STRING_COMPARE(myarg, "--png\0")){
                              opt_wrong = 0; opt_png = 1; }
                        if (!STRING_COMPARE(myarg, "--bmp\0")){
                              opt_wrong = 0; opt_bmp = 1; }
//                      if ((!STRING_COMPARE(myarg, "-R\0")) || (!STRING_COMPARE(myarg, "--recursive\0"))){
//                            opt_wrong = 0; opt_recursive = 1; }
                        if ((!STRING_COMPARE(myarg, "-s\0")) || (!STRING_COMPARE(myarg, "--silent\0")) || \
                              (!STRING_COMPARE(myarg, "--quiet\0"))){
                              opt_wrong = 0; opt_quiet = 1; }
                        if ((!STRING_COMPARE(myarg, "-V\0")) || (!STRING_COMPARE(myarg, "--verbose\0"))){
                              opt_wrong = 0; opt_verbose = 1; }
                        if (!STRING_COMPARE(myarg, "--test\0")){
                              opt_wrong = 0; opt_test = 1; opt_autoadjust = 1; }


                        // checking --output switch

                        // check if there was space between the --output switch and its parameter
                        // and if the parameter needs to be parsed separately
                        if (opt_output_space_flag){
                              opt_output_space_flag = 0;

                              int char_offs = 0;
                              int i = 0;
                              char output_ending = '\0';
                              while ((myarg[char_offs+i] != 0) && (i < max_char)){
                                    opt_output_path[i] = myarg[char_offs+i];
                                    output_ending = opt_output_path[i];
                                    i++;
                              }
                              // check if output path ends with slash character
                              // if not, then append it
                              if (output_ending != slsh[0]){
                                    opt_output_path [i] = slsh[0];
                                    i++;
                              }
                              opt_output_path [i] = 0;

                              // check if specified output directory is a dir and if it exists
                              DIR * dp;
                              dp = opendir(opt_output_path);
                              if (dp == NULL){
                                    STRING_PRINTE("error: bad directory parameter\n"); return 1; }

                              opt_output = 1;
                              opt_wrong = 0;
                        }

                        if ((!STRING_COMPARE_FIX(myarg, "-o", 2)) || (!STRING_COMPARE_FIX(myarg, "--output", 8))){
                              int char_offs;
                              if (!STRING_COMPARE_FIX(myarg, "--output", 8)){
                                    char_offs = 8;
                              }
                              else{
                                    char_offs = 2;
                              }

                              int i = 0;
                              // check if there is space between the switch and its parameter
                              if (myarg[char_offs+i] == 0){
                                    opt_output_space_flag = 1;
                                    opt_wrong = 0;
                              }
                              else{
                                    char output_ending = '\0';
                                    while ((myarg[char_offs+i] != 0) && (i < max_char)){
                                          opt_output_path[i] = myarg[char_offs+i];
                                          output_ending = opt_output_path[i];
                                          i++;
                                    }
                                    // check if output path ends with slash character
                                    // if not, then append it
                                    if (output_ending != slsh[0]){
                                          opt_output_path [i] = slsh[0];
                                          i++;
                                    }
                                    opt_output_path [i] = 0;

                                    // check if specified output directory is a dir and if it exists
                                    DIR * dp;
                                    dp = opendir(opt_output_path);
                                    if (dp == NULL){
                                          STRING_PRINTE("error: bad directory parameter\n"); return 1; }

                                    opt_output = 1;
                                    opt_wrong = 0;
                              }

                        }

                        // checking --quality switch

                        // check if there was space between the --quality switch and its parameter
                        // and if the parameter needs to be parsed separately
                        if (opt_quality_space_flag){
                              opt_quality_space_flag = 0;

                              char num [8+1] = "";
                              int num_max = 8;
                              int num_offs = 0;
                              int i = 0;
                              while ((myarg[num_offs+i] != 0) && (i < num_max)){
                                    num[i] = myarg[num_offs+i];
                                    i++;
                              }
                              num [i] = 0;
                              if (i >= num_max){ STRING_PRINTE("error: bad parameters\n"); return 1; }
                              if (STRING_CONVERT_TO_INTEGER(num, &opt_quality)){
                                    STRING_PRINTE("error: bad parameters\n"); return 1; }

                              if ((opt_quality >= 1) && (opt_quality <= 100)){ opt_wrong = 0; }
                              else{ STRING_PRINTE("error: bad parameters\n"); return 1; }
                        }

                        if ((!STRING_COMPARE_FIX(myarg, "-q", 2)) || (!STRING_COMPARE_FIX(myarg, "--quality", 9))){
                              char num [8+1] = "";
                              int num_max = 8;
                              int num_offs;
                              if (!STRING_COMPARE_FIX(myarg, "--quality", 9)){
                                    num_offs = 9;
                              }
                              else{
                                    num_offs = 2;
                              }

                              int i = 0;
                              // check if there is space between the switch and its parameter
                              if (myarg[num_offs+i] == 0){
                                    opt_quality_space_flag = 1;
                                    opt_wrong = 0;
                              }
                              else{
                                    while ((myarg[num_offs+i] != 0) && (i < num_max)){
                                          num[i] = myarg[num_offs+i];
                                          i++;
                                    }
                                    num [i] = 0;
                                    if (i >= num_max){ STRING_PRINTE("error: bad parameters\n"); return 1; }

                                    if (STRING_CONVERT_TO_INTEGER(num, &opt_quality)){
                                          STRING_PRINTE("error: bad parameters\n"); return 1; }
                                    if ((opt_quality >= 1) && (opt_quality <= 100)){ opt_wrong = 0; }
                                    else{ STRING_PRINTE("error: bad parameters\n"); return 1; }
                              }

                        }

                        // checking --resize switch

                        // check if there was space between the --resize switch and its parameter
                        // and if the parameter needs to be parsed separately
                        if (opt_resize_space_flag){
                              opt_resize_space_flag = 0;

                              char num [16+1] = "";
                              int num_max = 16;
                              int num_offs = 0;
                              int i = 0;
                              while ((myarg[num_offs+i] != 0) && (myarg[num_offs+i] != '%') && (i < num_max)){
                                    num[i] = myarg[num_offs+i];
                                    i++;
                              }
                              num [i] = 0;
                              if (i >= num_max){ STRING_PRINTE("error: bad parameters\n"); return 1; }
                              // is the resize value given in percentage?
                              if (myarg[num_offs+i] == '%') opt_resize_percent = 1;

                              if (STRING_CONVERT_TO_INTEGER(num, &opt_resize)){
                                    STRING_PRINTE("error: bad parameters\n"); return 1; }

                              if (opt_resize_percent){
                                    if ((opt_resize >= 1) && (opt_resize <= 100)){ opt_wrong = 0; }
                                    else{ STRING_PRINTE("error: bad parameters\n"); return 1; }
                              }
                              else{
                                    if ((opt_resize >= 1) && (opt_resize <= 100000)){ opt_wrong = 0; }
                                    else{ STRING_PRINTE("error: bad parameters\n"); return 1; }
                              }
                        }

                        if ((!STRING_COMPARE_FIX(myarg, "-r", 2)) || (!STRING_COMPARE_FIX(myarg, "--resize", 8))){
                              char num [16+1] = "";
                              int num_max = 16;
                              int num_offs;
                              if (!STRING_COMPARE_FIX(myarg, "--resize", 8)){
                                    num_offs = 8;
                              }
                              else{
                                    num_offs = 2;
                              }

                              int i = 0;
                              // check if there is space between the switch and its parameter

                              if (myarg[num_offs+i] == 0){
                                    opt_resize_space_flag = 1;
                                    opt_wrong = 0;
                              }
                              else{
                                    while ((myarg[num_offs+i] != 0) && (myarg[num_offs+i] != '%') && (i < num_max)){
                                          num[i] = myarg[num_offs+i];
                                          i++;
                                    }
                                    num [i] = 0;
                                    if (i >= num_max){ STRING_PRINTE("error: bad parameters\n"); return 1; }
                                    // is the resize value given in percentage?
                                    if (myarg[num_offs+i] == '%') opt_resize_percent = 1;

                                    if (STRING_CONVERT_TO_INTEGER(num, &opt_resize)){
                                          STRING_PRINTE("error: bad parameters\n"); return 1; }

                                    if (opt_resize_percent){
                                          if ((opt_resize >= 1) && (opt_resize <= 100)){ opt_wrong = 0; }
                                          else{ STRING_PRINTE("error: bad parameters\n"); return 1; }
                                    }
                                    else{
                                          if ((opt_resize >= 1) && (opt_resize <= 100000)){ opt_wrong = 0; }
                                          else{ STRING_PRINTE("error: bad parameters\n"); return 1; }
                                    }
                              }

                        }

                        // checking --rotate and --flip switches
                        if (!STRING_COMPARE(myarg, "--rotate90\0")){ opt_wrong = 0; opt_rotate90 = 1; }
                        if (!STRING_COMPARE(myarg, "--rotate180\0")){ opt_wrong = 0; opt_rotate180 = 1; }
                        if (!STRING_COMPARE(myarg, "--rotate270\0")){ opt_wrong = 0; opt_rotate270 = 1; }
                        if (!STRING_COMPARE(myarg, "--flipx\0")){ opt_wrong = 0; opt_flipx = 1; }
                        if (!STRING_COMPARE(myarg, "--flipy\0")){ opt_wrong = 0; opt_flipy = 1; }

                        // we remember if there were switches but given in bad way
                        if (opt_wrong){ opt_wrong_total = 1; }
                        else{ opt_counter++; }
                  }
                  else {
                        // expanding the file list that contains the files to be processed one by one
                        FILE_LIST_ADD(myarg);
                  }

            }

            // error message if bad parameters
            // error message also when missing extra parameter
            if ((opt_wrong_total) || (opt_quality_space_flag) || (opt_resize_space_flag) || (opt_output_space_flag)){
                  STRING_PRINTE("error: bad parameters\n"); return 1; }
            else{

                  // check if only 1 type of output format is specified on input
                  int format_cnt = 0;
                  if (opt_jpg) format_cnt++;
                  if (opt_jp2) format_cnt++;
                  if (opt_png) format_cnt++;
                  if (opt_bmp) format_cnt++;
                  if (format_cnt > 1){
                        STRING_PRINTE("error: only one output format allowed\n");
                        return 1; }

                  // managing info switches
                  if (opt_version) { PRINT_VERSION(); PRINT_LICENSE(); }
                  if (opt_help)    { PRINT_DESCRIPTION(); PRINT_HELP(); }

                  // AUTOADJUST DEFAULT = 1 IF NO OTHER PARAMETER EXCEPT FILE NAME
                  // if no parameters given except file names, then the --autoadjust parameter is 1 by default
                  if ((opt_counter <= 0) && (file_name_counter > 0)) { opt_autoadjust = 1; opt_counter++; }

                  // Main processing work of the switches (load -> process -> save)
                  // ------------------------------------------------------------------
                  // checking switches that need file name as input
                  if ((opt_autoadjust != 0) ||
                      (opt_overwrite  != 0) ||
                      (opt_noexif     != 0) ||
                      (opt_jpg        != 0) ||
                      (opt_jp2        != 0) ||
                      (opt_png        != 0) ||
                      (opt_bmp        != 0) ||
                      (opt_resize     != 0) ||
                      (opt_rotate90   != 0) ||
                      (opt_rotate180  != 0) ||
                      (opt_rotate270  != 0) ||
                      (opt_flipx      != 0) ||
                      (opt_flipy      != 0) ||
                      (opt_output     != 0) ||
                      (opt_quality    != 0) ||
                      (opt_recursive  != 0) ||
                      (opt_test       != 0)){

                        // were there any file names given as input?
                        if (file_name_counter > 0){

                              // if there are more than 1 files to read, then no error messages are print during process
                              //if (file_name_counter > 1) opt_quiet = 1;

                              // if the number of input files is greater than 0, then we process them one by one
                              char tt[max_char];
                              int c = 0;
                              int d;
                              int i;
                              for (i=0; i<file_name_counter; i++){
                                    d = 0;
                                    while (file_name_buffer[c] != 0){
                                          if (d >= max_char) return 255;
                                          if (c >= max_file_name_buffer) return 255;
                                          tt[d] = file_name_buffer[c];
                                          d++;
                                          c++;
                                    }
                                    tt[d] = 0; d++; c++;
                                    // --------------------------------------------------------
                                          if (MAIN_RUN(tt)) { result = 1; }
                                    // --------------------------------------------------------
                              }
                        }

                        // error here, because no input file names were given
                        else {
                              STRING_PRINTE("error: file name missing\n");
                              return 1;
                        }
                  }
            }
      }

      // if no switches or file names or any parameters were given,
      // -saying it other way the argument counter = 1 which is the command name itself-
      // then print something
      else {
            //PRINT_VERSION();
            //PRINT_DESCRIPTION();
            //PRINT_LICENSE();
            //PRINT_HELP();

            STRING_PRINTE("No parameters given. Use -h (--help) for more information\n");
      }

      return result;
}




int MAIN_INIT(void)
{
      // we store the unix time here (seconds)
      mytime = time(NULL);

      // number of files
      file_counter = 0;
      // number of files stored in file_name_buffer
      file_name_counter = 0;
      // pointer pointing to the end of the file names read from the files that are stored in file_name_buffer
      // saying it other way, it is the offset pointer pointing to the next file name
      file_name_buffer_pointer = 0;
      // allocating memory
      file_name_buffer = malloc(max_file_name_buffer);
      if (file_name_buffer == 0){
            STRING_PRINTE("error: memory allocation failure\n"); return 1; }

#ifndef __BMP_ONLY__
      bitmap_format_png_interlace_type = PNG_INTERLACE_NONE;
      bitmap_format_png_compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
      bitmap_format_png_filter_type = PNG_FILTER_TYPE_DEFAULT;
#endif

      // set default image resolution
      // 2835 dots per meter is equal to 72 dots per inch
      xdpi = 2835;
      ydpi = 2835;
      udpi = 1;

      return 0;
}



int main(int argc, char **argv)
{
      if (MAIN_INIT()) return 1;

      int result = 0;
      if (MAIN_ARGUMENTS_READ(argc, argv)){ result = 1; }

      free(file_name_buffer);

      return result;
}

Generated by  Doxygen 1.6.0   Back to index