Enable RAW codec for Windows

* Fix the exception catching
* Set preprocessor differently for MSVC

BUG=skia:4889(b/26958348)
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1738913002

Committed: https://skia.googlesource.com/skia/+/474e4c3dd28b67f590851321f15d9983ef7fd031

Review URL: https://codereview.chromium.org/1738913002
diff --git a/gyp/common_variables.gypi b/gyp/common_variables.gypi
index 0688f62..e26939f 100644
--- a/gyp/common_variables.gypi
+++ b/gyp/common_variables.gypi
@@ -53,19 +53,15 @@
         'skia_os%': '<(skia_os)',
         'vulkan_merged_into_skia': '1',
         'skia_android_framework%': 0,
+        # RAW codec needs exceptions. Due to that, it is a separate target. Its usage can be
+        # controlled by skia_codec_decodes_raw.
+        'skia_codec_decodes_raw%': 1,
         'conditions' : [
           [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "mac"]', {
             'skia_arch_type%': 'x86_64',
           }, {
             'skia_arch_type%': 'x86',
           }],
-          # RAW codec needs exceptions. Due to that, it is a separate target. Its usage can be
-          # controlled by skia_codec_decodes_raw.
-          ['skia_os == "win"', {
-            'skia_codec_decodes_raw%' : 0,
-          }, {
-            'skia_codec_decodes_raw%' : 1,
-          }],
         ],
         'arm_version%': 0,
         'arm_neon%': 0,
diff --git a/gyp/dng_sdk.gyp b/gyp/dng_sdk.gyp
index 7655fd3..3d42624 100644
--- a/gyp/dng_sdk.gyp
+++ b/gyp/dng_sdk.gyp
@@ -127,7 +127,16 @@
       'msvs_settings': {
         'VCCLCompilerTool': {
           'WarningLevel': '0',
-          'AdditionalOptions': ['/wd4189', ],
+          'AdditionalOptions': [
+            '/wd4189',
+            '/DqDNGBigEndian#0',
+            '/DqDNGReportErrors#0',
+            '/DqDNGThreadSafe#1',
+            '/DqDNGUseLibJPEG#1',
+            '/DqDNGUseXMP#0',
+            '/DqDNGValidate#0',
+            '/DqDNGValidateTarget#1',
+          ],
         },
       },
     }],
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index a006e50..9d0fb1c 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -10,17 +10,20 @@
 #include "SkColorPriv.h"
 #include "SkData.h"
 #include "SkJpegCodec.h"
+#include "SkMutex.h"
 #include "SkRawCodec.h"
 #include "SkRefCnt.h"
 #include "SkStream.h"
 #include "SkStreamPriv.h"
 #include "SkSwizzler.h"
+#include "SkTArray.h"
 #include "SkTaskGroup.h"
 #include "SkTemplates.h"
 #include "SkTypes.h"
 
 #include "dng_area_task.h"
 #include "dng_color_space.h"
+#include "dng_errors.h"
 #include "dng_exceptions.h"
 #include "dng_host.h"
 #include "dng_info.h"
@@ -105,15 +108,30 @@
         const std::vector<dng_rect> taskAreas = compute_task_areas(maxTasks, area, tileSize);
         const int numTasks = static_cast<int>(taskAreas.size());
 
+        SkMutex mutex;
+        SkTArray<dng_exception> exceptions;
         task.Start(numTasks, tileSize, &Allocator(), Sniffer());
         for (int taskIndex = 0; taskIndex < numTasks; ++taskIndex) {
-            taskGroup.add([&task, this, taskIndex, taskAreas, tileSize] {
-                task.ProcessOnThread(taskIndex, taskAreas[taskIndex], tileSize, this->Sniffer());
+            taskGroup.add([&mutex, &exceptions, &task, this, taskIndex, taskAreas, tileSize] {
+                try {
+                    task.ProcessOnThread(taskIndex, taskAreas[taskIndex], tileSize, this->Sniffer());
+                } catch (dng_exception& exception) {
+                    SkAutoMutexAcquire lock(mutex);
+                    exceptions.push_back(exception);
+                } catch (...) {
+                    SkAutoMutexAcquire lock(mutex);
+                    exceptions.push_back(dng_exception(dng_error_unknown));
+                }
             });
         }
 
         taskGroup.wait();
         task.Finish(numTasks);
+
+        // Currently we only re-throw the first catched exception.
+        if (!exceptions.empty()) {
+            Throw_dng_error(exceptions.front().ErrorCode(), nullptr, nullptr);
+        }
     }
 
     uint32 PerformAreaTaskThreads() override {
@@ -428,15 +446,15 @@
             }
         }
 
-        // render() takes ownership of fHost, fInfo, fNegative and fDngStream when available.
-        SkAutoTDelete<dng_host> host(fHost.release());
-        SkAutoTDelete<dng_info> info(fInfo.release());
-        SkAutoTDelete<dng_negative> negative(fNegative.release());
-        SkAutoTDelete<dng_stream> dngStream(fDngStream.release());
-
         // DNG SDK preserves the aspect ratio, so it only needs to know the longer dimension.
         const int preferredSize = SkTMax(width, height);
         try {
+            // render() takes ownership of fHost, fInfo, fNegative and fDngStream when available.
+            SkAutoTDelete<dng_host> host(fHost.release());
+            SkAutoTDelete<dng_info> info(fInfo.release());
+            SkAutoTDelete<dng_negative> negative(fNegative.release());
+            SkAutoTDelete<dng_stream> dngStream(fDngStream.release());
+
             host->SetPreferredSize(preferredSize);
             host->ValidateSizes();
 
@@ -506,11 +524,12 @@
     }
 
     bool readDng() {
-        // Due to the limit of DNG SDK, we need to reset host and info.
-        fHost.reset(new SkDngHost(&fAllocator));
-        fInfo.reset(new dng_info);
-        fDngStream.reset(new SkDngStream(fStream));
         try {
+            // Due to the limit of DNG SDK, we need to reset host and info.
+            fHost.reset(new SkDngHost(&fAllocator));
+            fInfo.reset(new dng_info);
+            fDngStream.reset(new SkDngStream(fStream));
+
             fHost->ValidateSizes();
             fInfo->Parse(*fHost, *fDngStream);
             fInfo->PostParse(*fHost);
diff --git a/tests/CodexTest.cpp b/tests/CodexTest.cpp
index a0789fb..37e4f30 100644
--- a/tests/CodexTest.cpp
+++ b/tests/CodexTest.cpp
@@ -397,7 +397,8 @@
     check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false, false);
 
     // RAW
-#if defined(SK_CODEC_DECODES_RAW)
+// Disable RAW tests for Win32.
+#if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32))
     check(r, "sample_1mp.dng", SkISize::Make(600, 338), false, false, false);
     check(r, "sample_1mp_rotated.dng", SkISize::Make(600, 338), false, false, false);
     check(r, "dng_with_preview.dng", SkISize::Make(600, 338), true, false, false);
@@ -596,7 +597,8 @@
     test_dimensions(r, "mandrill_16.png");
 
     // RAW
-#if defined(SK_CODEC_DECODES_RAW)
+// Disable RAW tests for Win32.
+#if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32))
     test_dimensions(r, "sample_1mp.dng");
     test_dimensions(r, "sample_1mp_rotated.dng");
     test_dimensions(r, "dng_with_preview.dng");
@@ -872,9 +874,10 @@
     SkMemoryStream fStream;
 };
 
+// Disable RAW tests for Win32.
+#if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32))
 // Test that the RawCodec works also for not asset stream. This will test the code path using
 // SkRawBufferedStream instead of SkRawAssetStream.
-#if defined(SK_CODEC_DECODES_RAW)
 DEF_TEST(Codec_raw_notseekable, r) {
     const char* path = "dng_with_preview.dng";
     SkString fullPath(GetResourcePath(path));
diff --git a/tools/dm_flags.json b/tools/dm_flags.json
index 636aba5..dd0154e 100644
--- a/tools/dm_flags.json
+++ b/tools/dm_flags.json
@@ -3389,6 +3389,86 @@
     "image", 
     "_", 
     ".SRW", 
+    "_", 
+    "image", 
+    "_", 
+    ".arw", 
+    "_", 
+    "image", 
+    "_", 
+    ".cr2", 
+    "_", 
+    "image", 
+    "_", 
+    ".dng", 
+    "_", 
+    "image", 
+    "_", 
+    ".nef", 
+    "_", 
+    "image", 
+    "_", 
+    ".nrw", 
+    "_", 
+    "image", 
+    "_", 
+    ".orf", 
+    "_", 
+    "image", 
+    "_", 
+    ".raf", 
+    "_", 
+    "image", 
+    "_", 
+    ".rw2", 
+    "_", 
+    "image", 
+    "_", 
+    ".pef", 
+    "_", 
+    "image", 
+    "_", 
+    ".srw", 
+    "_", 
+    "image", 
+    "_", 
+    ".ARW", 
+    "_", 
+    "image", 
+    "_", 
+    ".CR2", 
+    "_", 
+    "image", 
+    "_", 
+    ".DNG", 
+    "_", 
+    "image", 
+    "_", 
+    ".NEF", 
+    "_", 
+    "image", 
+    "_", 
+    ".NRW", 
+    "_", 
+    "image", 
+    "_", 
+    ".ORF", 
+    "_", 
+    "image", 
+    "_", 
+    ".RAF", 
+    "_", 
+    "image", 
+    "_", 
+    ".RW2", 
+    "_", 
+    "image", 
+    "_", 
+    ".PEF", 
+    "_", 
+    "image", 
+    "_", 
+    ".SRW", 
     "--match", 
     "~GLPrograms"
   ]
diff --git a/tools/dm_flags.py b/tools/dm_flags.py
index 7a62717..ec36268 100755
--- a/tools/dm_flags.py
+++ b/tools/dm_flags.py
@@ -165,6 +165,11 @@
     for raw_ext in r:
       blacklist.extend(('_ image _ .%s' % raw_ext).split(' '))
 
+  # Blacklist RAW images on Win32 tests due to out-of-memory issue
+  if 'Win' in bot and not '64' in bot:
+    for raw_ext in r:
+      blacklist.extend(('_ image _ .%s' % raw_ext).split(' '))
+
   match = []
   if 'Valgrind' in bot: # skia:3021
     match.append('~Threaded')