int main()

in tjexample.c [165:416]


int main(int argc, char **argv)
{
  tjscalingfactor scalingFactor = TJUNSCALED;
  int outSubsamp = -1, outQual = -1;
  tjtransform xform;
  int fastUpsample = 0, fastDCT = 0;
  int width, height;
  char *inFormat, *outFormat;
  FILE *jpegFile = NULL;
  unsigned char *imgBuf = NULL, *jpegBuf = NULL;
  int retval = 0, i, pixelFormat = TJPF_UNKNOWN;
  tjhandle tjInstance = NULL;

  if ((scalingFactors = tj3GetScalingFactors(&numScalingFactors)) == NULL)
    THROW_TJ("getting scaling factors");
  memset(&xform, 0, sizeof(tjtransform));

  if (argc < 3)
    usage(argv[0]);

  /* Parse arguments. */
  for (i = 3; i < argc; i++) {
    if (!strncasecmp(argv[i], "-sc", 3) && i < argc - 1) {
      int match = 0, temp1 = 0, temp2 = 0, j;

      if (sscanf(argv[++i], "%d/%d", &temp1, &temp2) < 2)
        usage(argv[0]);
      for (j = 0; j < numScalingFactors; j++) {
        if ((double)temp1 / (double)temp2 == (double)scalingFactors[j].num /
                                             (double)scalingFactors[j].denom) {
          scalingFactor = scalingFactors[j];
          match = 1;
          break;
        }
      }
      if (match != 1)
        usage(argv[0]);
    } else if (!strncasecmp(argv[i], "-su", 3) && i < argc - 1) {
      i++;
      if (!strncasecmp(argv[i], "g", 1))
        outSubsamp = TJSAMP_GRAY;
      else if (!strcasecmp(argv[i], "444"))
        outSubsamp = TJSAMP_444;
      else if (!strcasecmp(argv[i], "422"))
        outSubsamp = TJSAMP_422;
      else if (!strcasecmp(argv[i], "420"))
        outSubsamp = TJSAMP_420;
      else
        usage(argv[0]);
    } else if (!strncasecmp(argv[i], "-q", 2) && i < argc - 1) {
      outQual = atoi(argv[++i]);
      if (outQual < 1 || outQual > 100)
        usage(argv[0]);
    } else if (!strncasecmp(argv[i], "-g", 2))
      xform.options |= TJXOPT_GRAY;
    else if (!strcasecmp(argv[i], "-hflip"))
      xform.op = TJXOP_HFLIP;
    else if (!strcasecmp(argv[i], "-vflip"))
      xform.op = TJXOP_VFLIP;
    else if (!strcasecmp(argv[i], "-transpose"))
      xform.op = TJXOP_TRANSPOSE;
    else if (!strcasecmp(argv[i], "-transverse"))
      xform.op = TJXOP_TRANSVERSE;
    else if (!strcasecmp(argv[i], "-rot90"))
      xform.op = TJXOP_ROT90;
    else if (!strcasecmp(argv[i], "-rot180"))
      xform.op = TJXOP_ROT180;
    else if (!strcasecmp(argv[i], "-rot270"))
      xform.op = TJXOP_ROT270;
    else if (!strcasecmp(argv[i], "-custom"))
      xform.customFilter = customFilter;
    else if (!strncasecmp(argv[i], "-c", 2) && i < argc - 1) {
      if (sscanf(argv[++i], "%dx%d+%d+%d", &xform.r.w, &xform.r.h, &xform.r.x,
                 &xform.r.y) < 4 ||
          xform.r.x < 0 || xform.r.y < 0 || xform.r.w < 1 || xform.r.h < 1)
        usage(argv[0]);
      xform.options |= TJXOPT_CROP;
    } else if (!strcasecmp(argv[i], "-fastupsample")) {
      printf("Using fast upsampling code\n");
      fastUpsample = 1;
    } else if (!strcasecmp(argv[i], "-fastdct")) {
      printf("Using fastest DCT/IDCT algorithm\n");
      fastDCT = 1;
    } else usage(argv[0]);
  }

  /* Determine input and output image formats based on file extensions. */
  inFormat = strrchr(argv[1], '.');
  outFormat = strrchr(argv[2], '.');
  if (inFormat == NULL || outFormat == NULL || strlen(inFormat) < 2 ||
      strlen(outFormat) < 2)
    usage(argv[0]);
  inFormat = &inFormat[1];
  outFormat = &outFormat[1];

  if ((tjInstance = tj3Init(TJINIT_TRANSFORM)) == NULL)
    THROW_TJ("creating TurboJPEG instance");

  if (!strcasecmp(inFormat, "jpg")) {
    /* Input image is a JPEG image.  Decompress and/or transform it. */
    long size;
    int inSubsamp, inColorspace;
    int doTransform = (xform.op != TJXOP_NONE || xform.options != 0 ||
                       xform.customFilter != NULL);
    size_t jpegSize;

    /* Read the JPEG file into memory. */
    if ((jpegFile = fopen(argv[1], "rb")) == NULL)
      THROW_UNIX("opening input file");
    if (fseek(jpegFile, 0, SEEK_END) < 0 || ((size = ftell(jpegFile)) < 0) ||
        fseek(jpegFile, 0, SEEK_SET) < 0)
      THROW_UNIX("determining input file size");
    if (size == 0)
      THROW("determining input file size", "Input file contains no data");
    jpegSize = size;
    if (jpegSize > (unsigned long)INT_MAX)
      THROW("allocating JPEG buffer", "Input file is too large");
    if ((jpegBuf = tj3Alloc(jpegSize)) == NULL)
      THROW_UNIX("allocating JPEG buffer");
    if (fread(jpegBuf, jpegSize, 1, jpegFile) < 1)
      THROW_UNIX("reading input file");
    fclose(jpegFile);  jpegFile = NULL;

    if (doTransform) {
      /* Transform it. */
      unsigned char *dstBuf = NULL;  /* Dynamically allocate the JPEG buffer */
      size_t dstSize = 0;

      xform.options |= TJXOPT_TRIM;
      if (tj3Transform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize,
                       &xform) < 0) {
        tj3Free(dstBuf);
        THROW_TJ("transforming input image");
      }
      tj3Free(jpegBuf);
      jpegBuf = dstBuf;
      jpegSize = dstSize;
    }
    if (tj3Set(tjInstance, TJPARAM_FASTUPSAMPLE, fastUpsample) < 0)
      THROW_TJ("setting TJPARAM_FASTUPSAMPLE");
    if (tj3Set(tjInstance, TJPARAM_FASTDCT, fastDCT) < 0)
      THROW_TJ("setting TJPARAM_FASTDCT");

    if (tj3DecompressHeader(tjInstance, jpegBuf, jpegSize) < 0)
      THROW_TJ("reading JPEG header");
    width = tj3Get(tjInstance, TJPARAM_JPEGWIDTH);
    height = tj3Get(tjInstance, TJPARAM_JPEGHEIGHT);
    inSubsamp = tj3Get(tjInstance, TJPARAM_SUBSAMP);
    inColorspace = tj3Get(tjInstance, TJPARAM_COLORSPACE);

    if (tj3Get(tjInstance, TJPARAM_LOSSLESS))
      scalingFactor = TJUNSCALED;

    printf("%s Image:  %d x %d pixels, %s subsampling, %s colorspace\n",
           (doTransform ? "Transformed" : "Input"), width, height,
           subsampName[inSubsamp], colorspaceName[inColorspace]);

    if (!strcasecmp(outFormat, "jpg") && doTransform &&
        scalingFactor.num == 1 && scalingFactor.denom == 1 && outSubsamp < 0 &&
        outQual < 0) {
      /* Input image has been transformed, and no re-compression options
         have been selected.  Write the transformed image to disk and exit. */
      if ((jpegFile = fopen(argv[2], "wb")) == NULL)
        THROW_UNIX("opening output file");
      if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1)
        THROW_UNIX("writing output file");
      goto bailout;
    }

    /* Scaling and/or a non-JPEG output image format and/or compression options
       have been selected, so we need to decompress the input/transformed
       image. */
    if (tj3SetScalingFactor(tjInstance, scalingFactor) < 0)
      THROW_TJ("setting scaling factor");
    width = TJSCALED(width, scalingFactor);
    height = TJSCALED(height, scalingFactor);
    if (outSubsamp < 0)
      outSubsamp = inSubsamp;

    pixelFormat = TJPF_BGRX;
#if ULLONG_MAX > SIZE_MAX
    if ((unsigned long long)width * height * tjPixelSize[pixelFormat] >
        (unsigned long long)((size_t)-1))
      THROW("allocating uncompressed image buffer", "Image is too large");
#endif
    if ((imgBuf =
         (unsigned char *)malloc(sizeof(unsigned char) * width * height *
                                 tjPixelSize[pixelFormat])) == NULL)
      THROW_UNIX("allocating uncompressed image buffer");

    if (tj3Decompress8(tjInstance, jpegBuf, jpegSize, imgBuf, 0,
                       pixelFormat) < 0)
      THROW_TJ("decompressing JPEG image");
    tj3Free(jpegBuf);  jpegBuf = NULL;
  } else {
    /* Input image is not a JPEG image.  Load it into memory. */
    if ((imgBuf = tj3LoadImage8(tjInstance, argv[1], &width, 1, &height,
                                &pixelFormat)) == NULL)
      THROW_TJ("loading input image");
    if (outSubsamp < 0) {
      if (pixelFormat == TJPF_GRAY)
        outSubsamp = TJSAMP_GRAY;
      else
        outSubsamp = TJSAMP_444;
    }
    printf("Input Image:  %d x %d pixels\n", width, height);
  }

  printf("Output Image (%s):  %d x %d pixels", outFormat, width, height);

  if (!strcasecmp(outFormat, "jpg")) {
    /* Output image format is JPEG.  Compress the uncompressed image. */
    size_t jpegSize = 0;

    jpegBuf = NULL;  /* Dynamically allocate the JPEG buffer */

    if (outQual < 0)
      outQual = DEFAULT_QUALITY;
    printf(", %s subsampling, quality = %d\n", subsampName[outSubsamp],
           outQual);

    if (tj3Set(tjInstance, TJPARAM_SUBSAMP, outSubsamp) < 0)
      THROW_TJ("setting TJPARAM_SUBSAMP");
    if (tj3Set(tjInstance, TJPARAM_QUALITY, outQual) < 0)
      THROW_TJ("setting TJPARAM_QUALITY");
    if (tj3Set(tjInstance, TJPARAM_FASTDCT, fastDCT) < 0)
      THROW_TJ("setting TJPARAM_FASTDCT");
    if (tj3Compress8(tjInstance, imgBuf, width, 0, height, pixelFormat,
                     &jpegBuf, &jpegSize) < 0)
      THROW_TJ("compressing image");

    /* Write the JPEG image to disk. */
    if ((jpegFile = fopen(argv[2], "wb")) == NULL)
      THROW_UNIX("opening output file");
    if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1)
      THROW_UNIX("writing output file");
  } else {
    /* Output image format is not JPEG.  Save the uncompressed image
       directly to disk. */
    printf("\n");
    if (tj3SaveImage8(tjInstance, argv[2], imgBuf, width, 0, height,
                      pixelFormat) < 0)
      THROW_TJ("saving output image");
  }

bailout:
  tj3Free(imgBuf);
  tj3Destroy(tjInstance);
  tj3Free(jpegBuf);
  if (jpegFile) fclose(jpegFile);
  return retval;
}