<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 <NAME>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "rawspeedconfig.h"
#include "decoders/DngDecoderSlices.h"
#include "common/Common.h"                          // for uint32, getThrea...
#include "common/Point.h"                           // for iPoint2D
#include "decoders/RawDecoderException.h"           // for RawDecoderException
#include "decompressors/DeflateDecompressor.h"      // for DeflateDecompressor
#include "decompressors/JpegDecompressor.h"         // for JpegDecompressor
#include "decompressors/LJpegDecompressor.h"        // for LJpegDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/Endianness.h"                          // for Endianness::big
#include "io/IOException.h"                         // for IOException
#include "tiff/TiffEntry.h"                         // IWYU pragma: keep
#include "tiff/TiffIFD.h"                           // for getTiffEndianness
#include <algorithm>                                // for move
#include <cstdio>                                   // for size_t
#include <exception>                                // for exception
#include <memory>                                   // for allocator_traits...
#include <string>                                   // for string, operator+
#include <vector>                                   // for allocator, vector

using namespace std;

namespace RawSpeed {

void *DecodeThread(void *_this) {
  auto *me = (DngDecoderThread *)_this;
  DngDecoderSlices* parent = me->parent;
  try {
    parent->decodeSlice(me);
  } catch (const std::exception &exc) {
    parent->mRaw->setError(string(
        string("DNGDEcodeThread: Caught exception: ") + string(exc.what())));
  } catch (...) {
    parent->mRaw->setError("DNGDEcodeThread: Caught unhandled exception.");
  }
  return nullptr;
}

DngDecoderSlices::DngDecoderSlices(Buffer* file, const RawImage& img,
                                   int _compression)
    : mFile(file), mRaw(img) {
  mFixLjpeg = false;
  compression = _compression;
}

void DngDecoderSlices::addSlice(std::unique_ptr<DngSliceElement>&& slice) {
  slices.emplace(move(slice));
}

void DngDecoderSlices::startDecoding() {
#ifndef HAVE_PTHREAD
  DngDecoderThread t(this);
  while (!slices.empty()) {
    t.slices.emplace(move(slices.front()));
    slices.pop();
  }
  DecodeThread(&t);
#else
  // Create threads

  nThreads = getThreadCount();
  int slicesPerThread = ((int)slices.size() + nThreads - 1) / nThreads;
//  decodedSlices = 0;
  pthread_attr_t attr;
  /* Initialize and set thread detached attribute */
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  threads.reserve(nThreads);

  for (uint32 i = 0; i < nThreads; i++) {
    auto t = make_unique<DngDecoderThread>(this);
    for (int j = 0; j < slicesPerThread ; j++) {
      if (!slices.empty()) {
        t->slices.emplace(move(slices.front()));
        slices.pop();
      }
    }
    pthread_create(&t->threadid, &attr, DecodeThread, t.get());
    threads.emplace_back(move(t));
  }
  pthread_attr_destroy(&attr);

  void *status;
  for (auto& thread : threads) {
    pthread_join(thread->threadid, &status);
  }
  threads.clear();
#endif
}

void DngDecoderSlices::decodeSlice(DngDecoderThread* t) {
  if (compression == 1) {
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();

      UncompressedDecompressor decompressor(*mFile, e->byteOffset, e->byteCount,
                                            mRaw);

      size_t thisTileLength = e->offY + e->height > (uint32)mRaw->dim.y
                                  ? mRaw->dim.y - e->offY
                                  : e->height;<commit_msg>DngDecoderSlices::decodeSlice(): add some assertions.<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 <NAME>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "rawspeedconfig.h"
#include "decoders/DngDecoderSlices.h"
#include "common/Common.h"                          // for uint32, getThrea...
#include "common/Point.h"                           // for iPoint2D
#include "decoders/RawDecoderException.h"           // for RawDecoderException
#include "decompressors/DeflateDecompressor.h"      // for DeflateDecompressor
#include "decompressors/JpegDecompressor.h"         // for JpegDecompressor
#include "decompressors/LJpegDecompressor.h"        // for LJpegDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/Endianness.h"                          // for Endianness::big
#include "io/IOException.h"                         // for IOException
#include "tiff/TiffEntry.h"                         // IWYU pragma: keep
#include "tiff/TiffIFD.h"                           // for getTiffEndianness
#include <algorithm>                                // for move
#include <cassert>                                  // for assert
#include <cstdio>                                   // for size_t
#include <exception>                                // for exception
#include <memory>                                   // for allocator_traits...
#include <string>                                   // for string, operator+
#include <vector>                                   // for allocator, vector

using namespace std;

namespace RawSpeed {

void *DecodeThread(void *_this) {
  auto *me = (DngDecoderThread *)_this;
  DngDecoderSlices* parent = me->parent;
  try {
    parent->decodeSlice(me);
  } catch (const std::exception &exc) {
    parent->mRaw->setError(string(
        string("DNGDEcodeThread: Caught exception: ") + string(exc.what())));
  } catch (...) {
    parent->mRaw->setError("DNGDEcodeThread: Caught unhandled exception.");
  }
  return nullptr;
}

DngDecoderSlices::DngDecoderSlices(Buffer* file, const RawImage& img,
                                   int _compression)
    : mFile(file), mRaw(img) {
  mFixLjpeg = false;
  compression = _compression;
}

void DngDecoderSlices::addSlice(std::unique_ptr<DngSliceElement>&& slice) {
  slices.emplace(move(slice));
}

void DngDecoderSlices::startDecoding() {
#ifndef HAVE_PTHREAD
  DngDecoderThread t(this);
  while (!slices.empty()) {
    t.slices.emplace(move(slices.front()));
    slices.pop();
  }
  DecodeThread(&t);
#else
  // Create threads

  nThreads = getThreadCount();
  int slicesPerThread = ((int)slices.size() + nThreads - 1) / nThreads;
//  decodedSlices = 0;
  pthread_attr_t attr;
  /* Initialize and set thread detached attribute */
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  threads.reserve(nThreads);

  for (uint32 i = 0; i < nThreads; i++) {
    auto t = make_unique<DngDecoderThread>(this);
    for (int j = 0; j < slicesPerThread ; j++) {
      if (!slices.empty()) {
        t->slices.emplace(move(slices.front()));
        slices.pop();
      }
    }
    pthread_create(&t->threadid, &attr, DecodeThread, t.get());
    threads.emplace_back(move(t));
  }
  pthread_attr_destroy(&attr);

  void *status;
  for (auto& thread : threads) {
    pthread_join(thread->threadid, &status);
  }
  threads.clear();
#endif
}

void DngDecoderSlices::decodeSlice(DngDecoderThread* t) {
  assert(t);
  assert(mRaw->dim.x > 0);
  assert(mRaw->dim.y > 0);
  assert(mRaw->getCpp() > 0);
  assert(mBps > 0 && mBps <= 32);

  if (compression == 1) {
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();

      UncompressedDecompressor decompressor(*mFile, e->byteOffset, e->byteCount,
                                            mRaw);

      size_t thisTileLength = e->offY + e->height > (uint32)mRaw->dim.y
                                  ? mRaw->dim.y - e->offY
                                  : e->height;
{'fraction_non_alphanumeric': 0.11553356282271945, 'fraction_numerical': 0.007530120481927711, 'mean_word_length': 2.39554419284149, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 31, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7141434', 'n_tokens_mistral': 2899, 'n_tokens_neox': 2789, 'n_words': 715}