Merge commit '15274b901acb75d6d2433e8578f3cfbc6f4f5fd9' into mozjpeg

* commit '15274b901acb75d6d2433e8578f3cfbc6f4f5fd9': (98 commits)
  AppVeyor: Use SignPath release cert/only sign tags
  xform fuzz: Use only xform opts to set entropy alg
  jchuff.c: Test for out-of-range coefficients
  turbojpeg.h: Make customFilter() proto match doc
  ChangeLog.md: Fix typo
  djpeg: Fix -map option with 12-bit data precision
  Disallow color quantization with lossless decomp
  tj3Transform: Calc dst buf size from xformed dims
  README.md: Include link to project home page
  AppVeyor: Only add installers to zip file
  AppVeyor: Integrate with SignPath.io
  Fix build warnings/errs w/ -DNO_GETENV/-DNO_PUTENV
  GitHub: Fix x32 build
  Bump version to 3.0.0
  tjexample.c: Prevent integer overflow
  Disallow merged upsampling with lossless decomp
  SECURITY.md: Wordsmithing and clarifications
  GitHub: Add security policy
  ChangeLog.md: List CVE ID fixed by 9f756bc6
  jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
  ...
This commit is contained in:
Kornel
2024-12-23 01:10:55 +00:00
233 changed files with 49909 additions and 14231 deletions

View File

@@ -54,7 +54,7 @@
retval = -1; goto bailout; \
}
#define THROW_TJ(action) THROW(action, tjGetErrorStr2(tjInstance))
#define THROW_TJ(action) THROW(action, tj3GetErrorStr(tjInstance))
#define THROW_UNIX(action) THROW(action, strerror(errno))
@@ -63,7 +63,7 @@
const char *subsampName[TJ_NUMSAMP] = {
"4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
"4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1", "4:4:1"
};
const char *colorspaceName[TJ_NUMCS] = {
@@ -154,18 +154,16 @@ static void usage(char *programName)
printf("-fastdct = Use the fastest DCT/IDCT algorithm available\n\n");
printf("-accuratedct = Use the most accurate DCT/IDCT algorithm available\n\n");
exit(1);
}
int main(int argc, char **argv)
{
tjscalingfactor scalingFactor = { 1, 1 };
tjscalingfactor scalingFactor = TJUNSCALED;
int outSubsamp = -1, outQual = -1;
tjtransform xform;
int flags = 0;
int fastUpsample = 0, fastDCT = 0;
int width, height;
char *inFormat, *outFormat;
FILE *jpegFile = NULL;
@@ -173,7 +171,7 @@ int main(int argc, char **argv)
int retval = 0, i, pixelFormat = TJPF_UNKNOWN;
tjhandle tjInstance = NULL;
if ((scalingFactors = tjGetScalingFactors(&numScalingFactors)) == NULL)
if ((scalingFactors = tj3GetScalingFactors(&numScalingFactors)) == NULL)
THROW_TJ("getting scaling factors");
memset(&xform, 0, sizeof(tjtransform));
@@ -239,13 +237,10 @@ int main(int argc, char **argv)
xform.options |= TJXOPT_CROP;
} else if (!strcasecmp(argv[i], "-fastupsample")) {
printf("Using fast upsampling code\n");
flags |= TJFLAG_FASTUPSAMPLE;
fastUpsample = 1;
} else if (!strcasecmp(argv[i], "-fastdct")) {
printf("Using fastest DCT/IDCT algorithm\n");
flags |= TJFLAG_FASTDCT;
} else if (!strcasecmp(argv[i], "-accuratedct")) {
printf("Using most accurate DCT/IDCT algorithm\n");
flags |= TJFLAG_ACCURATEDCT;
fastDCT = 1;
} else usage(argv[0]);
}
@@ -264,7 +259,7 @@ int main(int argc, char **argv)
int inSubsamp, inColorspace;
int doTransform = (xform.op != TJXOP_NONE || xform.options != 0 ||
xform.customFilter != NULL);
unsigned long jpegSize;
size_t jpegSize;
/* Read the JPEG file into memory. */
if ((jpegFile = fopen(argv[1], "rb")) == NULL)
@@ -274,10 +269,10 @@ int main(int argc, char **argv)
THROW_UNIX("determining input file size");
if (size == 0)
THROW("determining input file size", "Input file contains no data");
jpegSize = (unsigned long)size;
jpegSize = size;
if (jpegSize > (unsigned long)INT_MAX)
THROW("allocating JPEG buffer", "Input file is too large");
if ((jpegBuf = (unsigned char *)tjAlloc(jpegSize)) == NULL)
if ((jpegBuf = tj3Alloc(jpegSize)) == NULL)
THROW_UNIX("allocating JPEG buffer");
if (fread(jpegBuf, jpegSize, 1, jpegFile) < 1)
THROW_UNIX("reading input file");
@@ -286,27 +281,37 @@ int main(int argc, char **argv)
if (doTransform) {
/* Transform it. */
unsigned char *dstBuf = NULL; /* Dynamically allocate the JPEG buffer */
unsigned long dstSize = 0;
size_t dstSize = 0;
if ((tjInstance = tjInitTransform()) == NULL)
if ((tjInstance = tj3Init(TJINIT_TRANSFORM)) == NULL)
THROW_TJ("initializing transformer");
xform.options |= TJXOPT_TRIM;
if (tjTransform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize,
&xform, flags) < 0) {
tjFree(dstBuf);
if (tj3Transform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize,
&xform) < 0) {
tj3Free(dstBuf);
THROW_TJ("transforming input image");
}
tjFree(jpegBuf);
tj3Free(jpegBuf);
jpegBuf = dstBuf;
jpegSize = dstSize;
} else {
if ((tjInstance = tjInitDecompress()) == NULL)
if ((tjInstance = tj3Init(TJINIT_DECOMPRESS)) == NULL)
THROW_TJ("initializing decompressor");
}
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 (tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height,
&inSubsamp, &inColorspace) < 0)
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,
@@ -328,6 +333,8 @@ int main(int argc, char **argv)
/* 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)
@@ -342,15 +349,16 @@ int main(int argc, char **argv)
tjPixelSize[pixelFormat])) == NULL)
THROW_UNIX("allocating uncompressed image buffer");
if (tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height,
pixelFormat, flags) < 0)
if (tj3Decompress8(tjInstance, jpegBuf, jpegSize, imgBuf, 0,
pixelFormat) < 0)
THROW_TJ("decompressing JPEG image");
tjFree(jpegBuf); jpegBuf = NULL;
tjDestroy(tjInstance); tjInstance = NULL;
tj3Free(jpegBuf); jpegBuf = NULL;
} else {
/* Input image is not a JPEG image. Load it into memory. */
if ((imgBuf = tjLoadImage(argv[1], &width, 1, &height, &pixelFormat,
0)) == NULL)
if ((tjInstance = tj3Init(TJINIT_COMPRESS)) == NULL)
THROW_TJ("initializing compressor");
if ((imgBuf = tj3LoadImage8(tjInstance, argv[1], &width, 1, &height,
&pixelFormat)) == NULL)
THROW_TJ("loading input image");
if (outSubsamp < 0) {
if (pixelFormat == TJPF_GRAY)
@@ -365,7 +373,7 @@ int main(int argc, char **argv)
if (!strcasecmp(outFormat, "jpg")) {
/* Output image format is JPEG. Compress the uncompressed image. */
unsigned long jpegSize = 0;
size_t jpegSize = 0;
jpegBuf = NULL; /* Dynamically allocate the JPEG buffer */
@@ -374,33 +382,38 @@ int main(int argc, char **argv)
printf(", %s subsampling, quality = %d\n", subsampName[outSubsamp],
outQual);
if ((tjInstance = tjInitCompress()) == NULL)
THROW_TJ("initializing compressor");
if (tjCompress2(tjInstance, imgBuf, width, 0, height, pixelFormat,
&jpegBuf, &jpegSize, outSubsamp, outQual, flags) < 0)
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");
tjDestroy(tjInstance); tjInstance = NULL;
tj3Destroy(tjInstance); tjInstance = NULL;
/* 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");
tjDestroy(tjInstance); tjInstance = NULL;
tj3Destroy(tjInstance); tjInstance = NULL;
fclose(jpegFile); jpegFile = NULL;
tjFree(jpegBuf); jpegBuf = NULL;
tj3Free(jpegBuf); jpegBuf = NULL;
} else {
/* Output image format is not JPEG. Save the uncompressed image
directly to disk. */
printf("\n");
if (tjSaveImage(argv[2], imgBuf, width, 0, height, pixelFormat, 0) < 0)
if (tj3SaveImage8(tjInstance, argv[2], imgBuf, width, 0, height,
pixelFormat) < 0)
THROW_TJ("saving output image");
}
bailout:
tjFree(imgBuf);
if (tjInstance) tjDestroy(tjInstance);
tjFree(jpegBuf);
tj3Free(imgBuf);
tj3Destroy(tjInstance);
tj3Free(jpegBuf);
if (jpegFile) fclose(jpegFile);
return retval;
}