Remove use of internal Skia jpeg struct

Copied (and slightly simplified) from [1] and [2].

I think this was the last direct use of things in the
Skia-internal folder src/images, so I removed that from
HWUI's search path to avoid regressions.

[1] https://github.com/google/skia/blob/7b3fb04bc3d4615ed90cf45fe32ccd03d2b5b0dd/src/images/SkJPEGWriteUtility.h#L32
[2] https://github.com/google/skia/blob/7b3fb04bc3d4615ed90cf45fe32ccd03d2b5b0dd/src/images/SkJPEGWriteUtility.cpp#L69

Change-Id: Ic1ee3c0185910f377c37c79b30f37f41c53da3f2
Bug: skbug.com/13983
diff --git a/libs/hwui/jni/YuvToJpegEncoder.cpp b/libs/hwui/jni/YuvToJpegEncoder.cpp
index 6c070fe..8874ef1 100644
--- a/libs/hwui/jni/YuvToJpegEncoder.cpp
+++ b/libs/hwui/jni/YuvToJpegEncoder.cpp
@@ -2,9 +2,7 @@
 #define LOG_TAG "YuvToJpegEncoder"
 
 #include "CreateJavaOutputStreamAdaptor.h"
-#include "SkJPEGWriteUtility.h"
 #include "SkStream.h"
-#include "SkTypes.h"
 #include "YuvToJpegEncoder.h"
 #include <ui/PixelFormat.h>
 #include <hardware/hardware.h>
@@ -13,6 +11,15 @@
 
 #include <csetjmp>
 
+extern "C" {
+    // We need to include stdio.h before jpeg because jpeg does not include it, but uses FILE
+    // See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/17
+    #include <stdio.h>
+    #include "jpeglib.h"
+    #include "jerror.h"
+    #include "jmorecfg.h"
+}
+
 YuvToJpegEncoder* YuvToJpegEncoder::create(int format, int* strides) {
     // Only ImageFormat.NV21 and ImageFormat.YUY2 are supported
     // for now.
@@ -39,11 +46,64 @@
     longjmp(err->jmp, 1);
 }
 
+/*
+ * Destination struct for directing decompressed pixels to a SkStream.
+ */
+static constexpr size_t kMgrBufferSize = 1024;
+struct skstream_destination_mgr : jpeg_destination_mgr {
+    skstream_destination_mgr(SkWStream* stream);
+
+    SkWStream* const fStream;
+
+    uint8_t fBuffer[kMgrBufferSize];
+};
+
+static void sk_init_destination(j_compress_ptr cinfo) {
+    skstream_destination_mgr* dest = (skstream_destination_mgr*)cinfo->dest;
+
+    dest->next_output_byte = dest->fBuffer;
+    dest->free_in_buffer = kMgrBufferSize;
+}
+
+static boolean sk_empty_output_buffer(j_compress_ptr cinfo) {
+    skstream_destination_mgr* dest = (skstream_destination_mgr*)cinfo->dest;
+
+    if (!dest->fStream->write(dest->fBuffer, kMgrBufferSize)) {
+        ERREXIT(cinfo, JERR_FILE_WRITE);
+        return FALSE;
+    }
+
+    dest->next_output_byte = dest->fBuffer;
+    dest->free_in_buffer = kMgrBufferSize;
+    return TRUE;
+}
+
+static void sk_term_destination(j_compress_ptr cinfo) {
+    skstream_destination_mgr* dest = (skstream_destination_mgr*)cinfo->dest;
+
+    size_t size = kMgrBufferSize - dest->free_in_buffer;
+    if (size > 0) {
+        if (!dest->fStream->write(dest->fBuffer, size)) {
+            ERREXIT(cinfo, JERR_FILE_WRITE);
+            return;
+        }
+    }
+
+    dest->fStream->flush();
+}
+
+skstream_destination_mgr::skstream_destination_mgr(SkWStream* stream)
+        : fStream(stream) {
+    this->init_destination = sk_init_destination;
+    this->empty_output_buffer = sk_empty_output_buffer;
+    this->term_destination = sk_term_destination;
+}
+
 bool YuvToJpegEncoder::encode(SkWStream* stream, void* inYuv, int width,
         int height, int* offsets, int jpegQuality) {
-    jpeg_compress_struct    cinfo;
-    ErrorMgr                err;
-    skjpeg_destination_mgr  sk_wstream(stream);
+    jpeg_compress_struct      cinfo;
+    ErrorMgr                  err;
+    skstream_destination_mgr  sk_wstream(stream);
 
     cinfo.err = jpeg_std_error(&err.pub);
     err.pub.error_exit = error_exit;