TurboJPEG: Update JPEG buf ptrs on comp/xform err

When using the in-memory destination manager, it is necessary to
explicitly call the destination manager's term_destination() method if
an error occurs.  That method is called by jpeg_finish_compress() but
not by jpeg_abort_compress().

This fixes a potential double free() that could occur if tjCompress*()
or tjTransform() returned an error and the calling application tried to
clean up a JPEG buffer that was dynamically re-allocated by one of those
functions.
diff --git a/ChangeLog.md b/ChangeLog.md
index 12e730a..f47980c 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -45,6 +45,11 @@
 generated when using the `tjLoadImage()` function to load a 16-bit binary PPM
 file into an extended RGB image buffer.
 
+9. Fixed an issue whereby, if a JPEG buffer was automatically re-allocated by
+one of the TurboJPEG compression or transform functions and an error
+subsequently occurred during compression or transformation, the JPEG buffer
+pointer passed by the application was not updated when the function returned.
+
 
 2.0.90 (2.1 beta1)
 ==================
diff --git a/fuzz/transform.cc b/fuzz/transform.cc
index 401018e..b8a7516 100644
--- a/fuzz/transform.cc
+++ b/fuzz/transform.cc
@@ -92,21 +92,37 @@
   if (!dstBufs[2])
     goto bailout;
 
-  tjTransform(handle, data, size, NUMXFORMS, dstBufs, dstSizes, transforms,
-              TJFLAG_LIMITSCANS | TJFLAG_NOREALLOC);
-
   maxBufSize = tjBufSize(width, height, jpegSubsamp);
 
-  /* Touch all of the output pixels in order to catch uninitialized reads
-     when using MemorySanitizer. */
-  for (t = 0; t < NUMXFORMS; t++) {
+  if (tjTransform(handle, data, size, NUMXFORMS, dstBufs, dstSizes, transforms,
+                  TJFLAG_LIMITSCANS | TJFLAG_NOREALLOC) == 0) {
+    /* Touch all of the output pixels in order to catch uninitialized reads
+       when using MemorySanitizer. */
+    for (t = 0; t < NUMXFORMS; t++) {
+      int sum = 0;
+
+      for (i = 0; i < dstSizes[t]; i++)
+        sum += dstBufs[t][i];
+
+      /* Prevent the code above from being optimized out.  This test should
+         never be true, but the compiler doesn't know that. */
+      if (sum > 255 * maxBufSize)
+        goto bailout;
+    }
+  }
+
+  transforms[0].options &= ~TJXOPT_COPYNONE;
+  free(dstBufs[0]);
+  dstBufs[0] = NULL;
+  dstSizes[0] = 0;
+
+  if (tjTransform(handle, data, size, 1, dstBufs, dstSizes, transforms,
+                  TJFLAG_LIMITSCANS) == 0) {
     int sum = 0;
 
-    for (i = 0; i < dstSizes[t]; i++)
-      sum += dstBufs[t][i];
+    for (i = 0; i < dstSizes[0]; i++)
+      sum += dstBufs[0][i];
 
-    /* Prevent the code above from being optimized out.  This test should never
-       be true, but the compiler doesn't know that. */
     if (sum > 255 * maxBufSize)
       goto bailout;
   }
diff --git a/turbojpeg.c b/turbojpeg.c
index 3500c78..793a3ee 100644
--- a/turbojpeg.c
+++ b/turbojpeg.c
@@ -720,7 +720,10 @@
   jpeg_finish_compress(cinfo);
 
 bailout:
-  if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
+  if (cinfo->global_state > CSTATE_START) {
+    if (alloc) (*cinfo->dest->term_destination) (cinfo);
+    jpeg_abort_compress(cinfo);
+  }
   free(row_pointer);
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
@@ -1088,7 +1091,10 @@
   jpeg_finish_compress(cinfo);
 
 bailout:
-  if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
+  if (cinfo->global_state > CSTATE_START) {
+    if (alloc) (*cinfo->dest->term_destination) (cinfo);
+    jpeg_abort_compress(cinfo);
+  }
   for (i = 0; i < MAX_COMPONENTS; i++) {
     free(tmpbuf[i]);
     free(inbuf[i]);
@@ -1886,7 +1892,7 @@
 {
   jpeg_transform_info *xinfo = NULL;
   jvirt_barray_ptr *srccoefs, *dstcoefs;
-  int retval = 0, i, jpegSubsamp, saveMarkers = 0;
+  int retval = 0, alloc = 1, i, jpegSubsamp, saveMarkers = 0;
   struct my_progress_mgr progress;
 
   GET_INSTANCE(handle);
@@ -1974,7 +1980,7 @@
   srccoefs = jpeg_read_coefficients(dinfo);
 
   for (i = 0; i < n; i++) {
-    int w, h, alloc = 1;
+    int w, h;
 
     if (!xinfo[i].crop) {
       w = dinfo->image_width;  h = dinfo->image_height;
@@ -2032,7 +2038,10 @@
   jpeg_finish_decompress(dinfo);
 
 bailout:
-  if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
+  if (cinfo->global_state > CSTATE_START) {
+    if (alloc) (*cinfo->dest->term_destination) (cinfo);
+    jpeg_abort_compress(cinfo);
+  }
   if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
   free(xinfo);
   if (this->jerr.warning) retval = -1;