<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

    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 "decompressors/SamsungV0Decompressor.h"
#include "common/Common.h"                // for ushort16, uint32, int32
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/Buffer.h"                    // for Buffer
#include "io/ByteStream.h"                // for ByteStream
#include "io/Endianness.h"                // for Endianness, Endianness::li...
#include "tiff/TiffEntry.h"               // for TiffEntry
#include "tiff/TiffIFD.h"                 // for TiffIFD
#include "tiff/TiffTag.h"                 // for TiffTag, TiffTag::IMAGELENGTH
#include <algorithm>                      // for max
#include <cassert>                        // for assert
#include <iterator>                       // for advance, begin, end, next
#include <vector>                         // for vector

namespace rawspeed {

SamsungV0Decompressor::SamsungV0Decompressor(const RawImage& image,
                                             const TiffIFD* raw,
                                             const Buffer* mFile)
    : AbstractSamsungDecompressor(image) {
  const uint32 width = mRaw->dim.x;
  const uint32 height = mRaw->dim.y;

  if (width == 0 || height == 0 || width < 16 || width > 5546 || height > 3714)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

  const TiffEntry* sliceOffsets = raw->getEntry(static_cast<TiffTag>(40976));
  if (sliceOffsets->type != TIFF_LONG || sliceOffsets->count != 1)
    ThrowRDE("Entry 40976 is corrupt");

  ByteStream bso(mFile, sliceOffsets->getU32(), 4 * height, Endianness::little);

  const uint32 offset = raw->getEntry(STRIPOFFSETS)->getU32();
  const uint32 count = raw->getEntry(STRIPBYTECOUNTS)->getU32();
  Buffer rbuf(mFile->getSubView(offset, count));
  ByteStream bsr(DataBuffer(rbuf, Endianness::little));

  computeStripes(bso, bsr);
}

// FIXME: this is very close to IiqDecoder::computeSripes()
void SamsungV0Decompressor::computeStripes(ByteStream bso, ByteStream bsr) {
  const uint32 height = mRaw->dim.y;

  std::vector<uint32> offsets;
  offsets.reserve(1 + height);
  for (uint32 y = 0; y < height; y++) {
    offsets.emplace_back(bso.getU32());
    if (y > 0 && offsets[y] <= offsets[y - 1])
      ThrowRDE("Offset for line %u is out of sequence.", y);
  }
  offsets.emplace_back(bsr.getSize());

  stripes.reserve(height);

  auto offset_iterator = std::begin(offsets);
  bsr.skipBytes(*offset_iterator);

  auto next_offset_iterator = std::next(offset_iterator);
  while (next_offset_iterator < std::end(offsets)) {
    assert(*next_offset_iterator > *offset_iterator);
    const auto size = *next_offset_iterator - *offset_iterator;
    assert(size > 0);

    stripes.emplace_back(bsr.getStream(size));

    std::advance(offset_iterator, 1);
    std::advance(next_offset_iterator, 1);
  }

  assert(stripes.size() == height);
}

void SamsungV0Decompressor::decompress() const {
  for (int y = 0; y < mRaw->dim.y; y++)
    decompressStrip(y, stripes[y]);

  // Swap red and blue pixels to get the final CFA pattern
  for (int y = 0; y < mRaw->dim.y - 1; y += 2) {
    auto* topline = reinterpret_cast<ushort16*>(mRaw->getData(0, y));
    auto* bottomline = reinterpret_cast<ushort16*>(mRaw->getData(0, y + 1));

    for (int x = 0; x < mRaw->dim.x - 1; x += 2) {
      ushort16 temp = topline[1];
      topline[1] = bottomline[0];
      bottomline[0] = temp;

      topline += 2;
      bottomline += 2;
    }
  }
}

int32 SamsungV0Decompressor::calcAdj(BitPumpMSB32* bits, int b) {
  int32 adj = 0;
  if (b)
    adj = (static_cast<int32>(bits->getBits(b)) << (32 - b) >> (32 - b));
  return adj;
}

void SamsungV0Decompressor::decompressStrip(uint32 y,
                                            const ByteStream& bs) const {
  const uint32 width = mRaw->dim.x;

  BitPumpMSB32 bits(bs);

  int len[4];
  for (int& i : len)
    i = y < 2 ? 7 : 4;

  auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, y));
  const auto* const past_last =
      reinterpret_cast<ushort16*>(mRaw->getData(width - 1, y) + mRaw->getBpp());
  ushort16* img_up = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(y) - 1)));
  ushort16* img_up2 = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(y) - 2)));

  // Image is arranged in groups of 16 pixels horizontally
  for (uint32 x = 0; x < width; x += 16) {
    bits.fill();
    bool dir = !!bits.getBitsNoFill(1);

    int op[4];
    for (int& i : op)
      i = bits.getBitsNoFill(2);

    for (int i = 0; i < 4; i++) {
      assert(op[i] >= 0 && op[i] <= 3);

      switch (op[i]) {
      case 3:
        len[i] = bits.getBits(4);
        break;
      case 2:
        len[i]--;
        break;
      case 1:
        len[i]++;
        break;
      default:
        // FIXME: it can be zero too.
        break;
      }

      if (len[i] < 0)
        ThrowRDE("Bit length less than 0.");
      if (len[i] > 16)
        ThrowRDE("Bit Length more than 16.");
    }

    if (dir) {
      // Upward prediction
      // First we decode even pixels
      for (int c = 0; c < 16; c += 2) {
        int b = len[c >> 3];
        int32 adj = calcAdj(&bits, b);

        img[c] = adj + img_up[c];
      }

      // Now we decode odd pixels
      // Why on earth upward prediction only looks up 1 line above
      // is beyond me, it will hurt compression a deal.
      for (int c = 1; c < 16; c += 2) {
        int b = len[2 | (c >> 3)];
        int32 adj = calcAdj(&bits, b);

        img[c] = adj + img_up2[c];
      }
    } else {
      // Left to right prediction
      // First we decode even pixels
      int pred_left = x != 0 ? img[-2] : 128;
      for (int c = 0; c < 16; c += 2) {
        int b = len[c >> 3];
        int32 adj = calcAdj(&bits, b);

        if (img + c < past_last)
          img[c] = adj + pred_left;
      }

      // Now we decode odd pixels
      pred_left = x != 0 ? img[-1] : 128;
      for (int c = 1; c < 16; c += 2) {
        int b = len[2 | (c >> 3)];
        int32 adj = calcAdj(&bits, b);

        if (img + c < past_last)
          img[c] = adj + pred_left;
      }
    }

    img += 16;
    img_up += 16;
    img_up2 += 16;
  }
}

} // namespace rawspeed
<commit_msg>SamsungV0Decompressor::computeStripes(): rework slice size check<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

    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 "decompressors/SamsungV0Decompressor.h"
#include "common/Common.h"                // for ushort16, uint32, int32
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/Buffer.h"                    // for Buffer
#include "io/ByteStream.h"                // for ByteStream
#include "io/Endianness.h"                // for Endianness, Endianness::li...
#include "tiff/TiffEntry.h"               // for TiffEntry
#include "tiff/TiffIFD.h"                 // for TiffIFD
#include "tiff/TiffTag.h"                 // for TiffTag, TiffTag::IMAGELENGTH
#include <algorithm>                      // for max
#include <cassert>                        // for assert
#include <iterator>                       // for advance, begin, end, next
#include <vector>                         // for vector

namespace rawspeed {

SamsungV0Decompressor::SamsungV0Decompressor(const RawImage& image,
                                             const TiffIFD* raw,
                                             const Buffer* mFile)
    : AbstractSamsungDecompressor(image) {
  const uint32 width = mRaw->dim.x;
  const uint32 height = mRaw->dim.y;

  if (width == 0 || height == 0 || width < 16 || width > 5546 || height > 3714)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

  const TiffEntry* sliceOffsets = raw->getEntry(static_cast<TiffTag>(40976));
  if (sliceOffsets->type != TIFF_LONG || sliceOffsets->count != 1)
    ThrowRDE("Entry 40976 is corrupt");

  ByteStream bso(mFile, sliceOffsets->getU32(), 4 * height, Endianness::little);

  const uint32 offset = raw->getEntry(STRIPOFFSETS)->getU32();
  const uint32 count = raw->getEntry(STRIPBYTECOUNTS)->getU32();
  Buffer rbuf(mFile->getSubView(offset, count));
  ByteStream bsr(DataBuffer(rbuf, Endianness::little));

  computeStripes(bso, bsr);
}

// FIXME: this is very close to IiqDecoder::computeSripes()
void SamsungV0Decompressor::computeStripes(ByteStream bso, ByteStream bsr) {
  const uint32 height = mRaw->dim.y;

  std::vector<uint32> offsets;
  offsets.reserve(1 + height);
  for (uint32 y = 0; y < height; y++)
    offsets.emplace_back(bso.getU32());
  offsets.emplace_back(bsr.getSize());

  stripes.reserve(height);

  auto offset_iterator = std::begin(offsets);
  bsr.skipBytes(*offset_iterator);

  auto next_offset_iterator = std::next(offset_iterator);
  while (next_offset_iterator < std::end(offsets)) {
    if (*offset_iterator >= *next_offset_iterator)
      ThrowRDE("Line offsets are out of sequence or slice is empty.");

    const auto size = *next_offset_iterator - *offset_iterator;
    assert(size > 0);

    stripes.emplace_back(bsr.getStream(size));

    std::advance(offset_iterator, 1);
    std::advance(next_offset_iterator, 1);
  }

  assert(stripes.size() == height);
}

void SamsungV0Decompressor::decompress() const {
  for (int y = 0; y < mRaw->dim.y; y++)
    decompressStrip(y, stripes[y]);

  // Swap red and blue pixels to get the final CFA pattern
  for (int y = 0; y < mRaw->dim.y - 1; y += 2) {
    auto* topline = reinterpret_cast<ushort16*>(mRaw->getData(0, y));
    auto* bottomline = reinterpret_cast<ushort16*>(mRaw->getData(0, y + 1));

    for (int x = 0; x < mRaw->dim.x - 1; x += 2) {
      ushort16 temp = topline[1];
      topline[1] = bottomline[0];
      bottomline[0] = temp;

      topline += 2;
      bottomline += 2;
    }
  }
}

int32 SamsungV0Decompressor::calcAdj(BitPumpMSB32* bits, int b) {
  int32 adj = 0;
  if (b)
    adj = (static_cast<int32>(bits->getBits(b)) << (32 - b) >> (32 - b));
  return adj;
}

void SamsungV0Decompressor::decompressStrip(uint32 y,
                                            const ByteStream& bs) const {
  const uint32 width = mRaw->dim.x;

  BitPumpMSB32 bits(bs);

  int len[4];
  for (int& i : len)
    i = y < 2 ? 7 : 4;

  auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, y));
  const auto* const past_last =
      reinterpret_cast<ushort16*>(mRaw->getData(width - 1, y) + mRaw->getBpp());
  ushort16* img_up = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(y) - 1)));
  ushort16* img_up2 = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(y) - 2)));

  // Image is arranged in groups of 16 pixels horizontally
  for (uint32 x = 0; x < width; x += 16) {
    bits.fill();
    bool dir = !!bits.getBitsNoFill(1);

    int op[4];
    for (int& i : op)
      i = bits.getBitsNoFill(2);

    for (int i = 0; i < 4; i++) {
      assert(op[i] >= 0 && op[i] <= 3);

      switch (op[i]) {
      case 3:
        len[i] = bits.getBits(4);
        break;
      case 2:
        len[i]--;
        break;
      case 1:
        len[i]++;
        break;
      default:
        // FIXME: it can be zero too.
        break;
      }

      if (len[i] < 0)
        ThrowRDE("Bit length less than 0.");
      if (len[i] > 16)
        ThrowRDE("Bit Length more than 16.");
    }

    if (dir) {
      // Upward prediction
      // First we decode even pixels
      for (int c = 0; c < 16; c += 2) {
        int b = len[c >> 3];
        int32 adj = calcAdj(&bits, b);

        img[c] = adj + img_up[c];
      }

      // Now we decode odd pixels
      // Why on earth upward prediction only looks up 1 line above
      // is beyond me, it will hurt compression a deal.
      for (int c = 1; c < 16; c += 2) {
        int b = len[2 | (c >> 3)];
        int32 adj = calcAdj(&bits, b);

        img[c] = adj + img_up2[c];
      }
    } else {
      // Left to right prediction
      // First we decode even pixels
      int pred_left = x != 0 ? img[-2] : 128;
      for (int c = 0; c < 16; c += 2) {
        int b = len[c >> 3];
        int32 adj = calcAdj(&bits, b);

        if (img + c < past_last)
          img[c] = adj + pred_left;
      }

      // Now we decode odd pixels
      pred_left = x != 0 ? img[-1] : 128;
      for (int c = 1; c < 16; c += 2) {
        int b = len[2 | (c >> 3)];
        int32 adj = calcAdj(&bits, b);

        if (img + c < past_last)
          img[c] = adj + pred_left;
      }
    }

    img += 16;
    img_up += 16;
    img_up2 += 16;
  }
}

} // namespace rawspeed
<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

    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 "decompressors/SamsungV2Decompressor.h"
#include "common/Common.h"                // for uint32_t, uint16_t, int32_t
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/ByteStream.h"                // for ByteStream
#include <algorithm>                      // for max
#include <cassert>                        // for assert
#include <type_traits>                    // for underlying_type, underlyin...

namespace rawspeed {

// Seriously Samsung just use lossless jpeg already, it compresses better too :)

// Thanks to Michael Reichmann (Luminous Landscape) for putting Pedro Côrte-Real
// in contact and Loring von Palleske (Samsung) for pointing to the open-source
// code of Samsung's DNG converter at http://opensource.samsung.com/

enum struct SamsungV2Decompressor::OptFlags : uint32_t {
  NONE = 0U,       // no flags
  SKIP = 1U << 0U, // Skip checking if we need differences from previous line
  MV = 1U << 1U,   // Simplify motion vector definition
  QP = 1U << 2U,   // Don't scale the diff values

  // all possible flags
  ALL = SKIP | MV | QP,
};

constexpr SamsungV2Decompressor::OptFlags
operator|(SamsungV2Decompressor::OptFlags lhs,
          SamsungV2Decompressor::OptFlags rhs) {
  return static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) |
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
}

constexpr bool operator&(SamsungV2Decompressor::OptFlags lhs,
                         SamsungV2Decompressor::OptFlags rhs) {
  return SamsungV2Decompressor::OptFlags::NONE !=
         static_cast<SamsungV2Decompressor::OptFlags>(
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 lhs) &
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 rhs));
}

inline int32_t SamsungV2Decompressor::getDiff(BitPumpMSB32* pump,
                                              uint32_t len) {
  if (len == 0)
    return 0;
  int32_t diff = pump->getBits(len);
  // If the first bit is 1 we need to turn this into a negative number
  if (diff >> (len - 1))
    diff -= (1 << len);
  return diff;
}

SamsungV2Decompressor::SamsungV2Decompressor(const RawImage& image,
                                             const ByteStream& bs, int bit)
    : AbstractSamsungDecompressor(image), bits(bit) {
  if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
      mRaw->getBpp() != 2)
    ThrowRDE("Unexpected component count / data type");

  switch (bit) {
  case 12:
  case 14:
    break;
  default:
    ThrowRDE("Unexpected bit per pixel (%u)", bit);
  }

  static constexpr const auto headerSize = 16;
  bs.check(headerSize);

  BitPumpMSB32 startpump(bs);

  // Process the initial metadata bits, we only really use initVal, width and
  // height (the last two match the TIFF values anyway)
  startpump.getBits(16); // NLCVersion
  startpump.getBits(4);  // ImgFormat
  bitDepth = startpump.getBits(4) + 1;
  startpump.getBits(4); // NumBlkInRCUnit
  startpump.getBits(4); // CompressionRatio
  width = startpump.getBits(16);
  height = startpump.getBits(16);
  startpump.getBits(16); // TileWidth
  startpump.getBits(4);  // reserved

  // The format includes an optimization code that sets 3 flags to change the
  // decoding parameters
  const uint32_t optflags = startpump.getBits(4);
  if (optflags > static_cast<uint32_t>(OptFlags::ALL))
    ThrowRDE("Invalid opt flags %x", optflags);
  _flags = static_cast<OptFlags>(optflags);

  startpump.getBits(8); // OverlapWidth
  startpump.getBits(8); // reserved
  startpump.getBits(8); // Inc
  startpump.getBits(2); // reserved
  initVal = startpump.getBits(14);

  assert(startpump.getPosition() == headerSize);

  if (width == 0 || height == 0 || width % 16 != 0 || width > 6496 ||
      height > 4336)
    ThrowRDE("Unexpected image dimensions found: (%i; %i)", width, height);

  if (width != mRaw->dim.x || height != mRaw->dim.y)
    ThrowRDE("EXIF image dimensions do not match dimensions from raw header");

  data = startpump.getStream(startpump.getRemainSize());
}

void SamsungV2Decompressor::decompress() {
  switch (_flags) {
  case OptFlags::NONE:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::NONE>(row);
    break;
  case OptFlags::ALL:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::ALL>(row);
    break;

  case OptFlags::SKIP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP>(row);
    break;
  case OptFlags::MV:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::MV>(row);
    break;
  case OptFlags::QP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::QP>(row);
    break;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
  case OptFlags::SKIP | OptFlags::MV:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::MV>(row);
    break;
  case OptFlags::SKIP | OptFlags::QP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::QP>(row);
    break;

  case OptFlags::MV | OptFlags::QP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::MV | OptFlags::QP>(row);
    break;
#pragma GCC diagnostic pop

  default:
    __builtin_unreachable();
  }
}

// The format is relatively straightforward. Each line gets encoded as a set
// of differences from pixels from another line. Pixels are grouped in blocks
// of 16 (8 green, 8 red or blue). Each block is encoded in three sections.
// First 1 or 4 bits to specify which reference pixels to use, then a section
// that specifies for each pixel the number of bits in the difference, then
// the actual difference bits

template <SamsungV2Decompressor::OptFlags optflags>
inline void SamsungV2Decompressor::prepareBaselineValues(BitPumpMSB32* pump,
                                                         int row, int col) {
  const Array2DRef<uint16_t> out(mRaw->getU16DataAsUncroppedArray2DRef());

  if (!(optflags & OptFlags::QP) && !(col & 63)) {
    static constexpr std::array<int32_t, 3> scalevals = {{0, -2, 2}};
    uint32_t i = pump->getBits(2);
    scale = i < 3 ? scale + scalevals[i] : pump->getBits(12);
  }

  // First we figure out which reference pixels mode we're in
  if (optflags & OptFlags::MV)
    motion = pump->getBits(1) ? 3 : 7;
  else if (!pump->getBits(1))
    motion = pump->getBits(3);

  if ((row == 0 || row == 1) && (motion != 7))
    ThrowRDE("At start of image and motion isn't 7. File corrupted?");

  if (motion == 7) {
    // The base case, just set all pixels to the previous ones on the same
    // line If we're at the left edge we just start at the initial value
    for (int i = 0; i < 16; i++)
      out(row, col + i) = (col == 0) ? initVal : out(row, col + i - 2);
    return;
  }

  // The complex case, we now need to actually lookup one or two lines above
  if (row < 2)
    ThrowRDE("Got a previous line lookup on first two lines. File corrupted?");

  static constexpr std::array<int32_t, 7> motionOffset = {-4, -2, -2, 0,
                                                          0,  2,  4};
  static constexpr std::array<int32_t, 7> motionDoAverage = {0, 0, 1, 0,
                                                             1, 0, 0};

  int32_t slideOffset = motionOffset[motion];
  int32_t doAverage = motionDoAverage[motion];

  for (int i = 0; i < 16; i++) {
    int refRow = row;
    int refCol = col + i + slideOffset;

    if ((row + i) & 1) { // Red or blue pixels use same color two lines up
      refRow -= 2;
    } else { // Green pixel N uses Green pixel N from row above
      refRow -= 1;
      refCol += (i & 1) ? -1 : 1; // (top left or top right)
    }

    if (refCol < 0)
      ThrowRDE("Bad motion %u at the beginning of the row", motion);
    if ((refCol >= width) || (doAverage && (refCol + 2 >= width)))
      ThrowRDE("Bad motion %u at the end of the row", motion);

    // In some cases we use as reference interpolation of this pixel and
    // the next
    if (doAverage) {
      out(row, col + i) =
          (out(refRow, refCol) + out(refRow, refCol + 2) + 1) >> 1;
    } else
      out(row, col + i) = out(refRow, refCol);
  }
}

template <SamsungV2Decompressor::OptFlags optflags>
inline std::array<uint32_t, 4>
SamsungV2Decompressor::decodeDiffLengths(BitPumpMSB32* pump, int row) {
  // Figure out how many difference bits we have to read for each pixel
  std::array<uint32_t, 4> diffBits = {};
  if (optflags & OptFlags::SKIP || !pump->getBits(1)) {
    std::array<uint32_t, 4> flags;
    for (unsigned int& flag : flags)
      flag = pump->getBits(2);

    for (int i = 0; i < 4; i++) {
      // The color is 0-Green 1-Blue 2-Red
      uint32_t colornum = (row % 2 != 0) ? i >> 1 : ((i >> 1) + 2) % 3;

      assert(flags[i] <= 3);
      switch (flags[i]) {
      case 0:
        diffBits[i] = diffBitsMode[colornum][0];
        break;
      case 1:
        diffBits[i] = diffBitsMode[colornum][0] + 1;
        break;
      case 2:
        if (diffBitsMode[colornum][0] == 0)
          ThrowRDE("Difference bits underflow. File corrupted?");
        diffBits[i] = diffBitsMode[colornum][0] - 1;
        break;
      case 3:
        diffBits[i] = pump->getBits(4);
        break;
      default:
        __builtin_unreachable();
      }

      diffBitsMode[colornum][0] = diffBitsMode[colornum][1];
      diffBitsMode[colornum][1] = diffBits[i];

      if (diffBits[i] > bitDepth + 1)
        ThrowRDE("Too many difference bits. File corrupted?");
    }
  }

  return diffBits;
}

template <SamsungV2Decompressor::OptFlags optflags>
inline std::array<int, 16>
SamsungV2Decompressor::decodeDifferences(BitPumpMSB32* pump, int row) {
  std::array<int, 16> diffs;

  // Figure out how many difference bits we have to read for each pixel
  const std::array<uint32_t, 4> diffBits =
      decodeDiffLengths<optflags>(pump, row);

  // Actually read the differences and reshuffle them.
  for (int i = 0; i < 16; i++) {
    uint32_t len = diffBits[i >> 2];
    int32_t diff = getDiff(pump, len);

    int p;
    // The differences are stored interlaced:
    // 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
    if (row % 2)
      p = ((i % 8) << 1) - (i >> 3) + 1;
    else
      p = ((i % 8) << 1) + (i >> 3);

    diffs[p] = diff * (scale * 2 + 1) + scale;
  }

  return diffs;
}

template <SamsungV2Decompressor::OptFlags optflags>
void SamsungV2Decompressor::decompressRow(int row) {
  const Array2DRef<uint16_t> out(mRaw->getU16DataAsUncroppedArray2DRef());

  // Align pump to 16byte boundary
  const auto line_offset = data.getPosition();
  if ((line_offset & 0xf) != 0)
    data.skipBytes(16 - (line_offset & 0xf));

  BitPumpMSB32 pump(data);

  // Initialize the motion and diff modes at the start of the line
  motion = 7;
  // By default we are not scaling values at all
  scale = 0;

  for (auto& i : diffBitsMode)
    i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;

  assert(width >= 16);
  assert(width % 16 == 0);
  for (int col = 0; col < width; col += 16) {
    prepareBaselineValues<optflags>(&pump, row, col);

    // Figure out how many difference bits we have to read for each pixel
    const std::array<int, 16> diffs = decodeDifferences<optflags>(&pump, row);

    // Actually apply the differences and write them to the pixels
    for (int i = 0; i < 16; i++) {
      int diff = diffs[i];

      uint16_t& pixel = out(row, col + i);
      pixel = clampBits(static_cast<int>(pixel) + diff, bits);
    }
  }

  data.skipBytes(pump.getBufferPosition());
}

} // namespace rawspeed
<commit_msg>SamsungV2Decompressor::decodeDiffLengths(): early return<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

    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 "decompressors/SamsungV2Decompressor.h"
#include "common/Common.h"                // for uint32_t, uint16_t, int32_t
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/ByteStream.h"                // for ByteStream
#include <algorithm>                      // for max
#include <cassert>                        // for assert
#include <type_traits>                    // for underlying_type, underlyin...

namespace rawspeed {

// Seriously Samsung just use lossless jpeg already, it compresses better too :)

// Thanks to Michael Reichmann (Luminous Landscape) for putting Pedro Côrte-Real
// in contact and Loring von Palleske (Samsung) for pointing to the open-source
// code of Samsung's DNG converter at http://opensource.samsung.com/

enum struct SamsungV2Decompressor::OptFlags : uint32_t {
  NONE = 0U,       // no flags
  SKIP = 1U << 0U, // Skip checking if we need differences from previous line
  MV = 1U << 1U,   // Simplify motion vector definition
  QP = 1U << 2U,   // Don't scale the diff values

  // all possible flags
  ALL = SKIP | MV | QP,
};

constexpr SamsungV2Decompressor::OptFlags
operator|(SamsungV2Decompressor::OptFlags lhs,
          SamsungV2Decompressor::OptFlags rhs) {
  return static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) |
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
}

constexpr bool operator&(SamsungV2Decompressor::OptFlags lhs,
                         SamsungV2Decompressor::OptFlags rhs) {
  return SamsungV2Decompressor::OptFlags::NONE !=
         static_cast<SamsungV2Decompressor::OptFlags>(
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 lhs) &
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 rhs));
}

inline int32_t SamsungV2Decompressor::getDiff(BitPumpMSB32* pump,
                                              uint32_t len) {
  if (len == 0)
    return 0;
  int32_t diff = pump->getBits(len);
  // If the first bit is 1 we need to turn this into a negative number
  if (diff >> (len - 1))
    diff -= (1 << len);
  return diff;
}

SamsungV2Decompressor::SamsungV2Decompressor(const RawImage& image,
                                             const ByteStream& bs, int bit)
    : AbstractSamsungDecompressor(image), bits(bit) {
  if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
      mRaw->getBpp() != 2)
    ThrowRDE("Unexpected component count / data type");

  switch (bit) {
  case 12:
  case 14:
    break;
  default:
    ThrowRDE("Unexpected bit per pixel (%u)", bit);
  }

  static constexpr const auto headerSize = 16;
  bs.check(headerSize);

  BitPumpMSB32 startpump(bs);

  // Process the initial metadata bits, we only really use initVal, width and
  // height (the last two match the TIFF values anyway)
  startpump.getBits(16); // NLCVersion
  startpump.getBits(4);  // ImgFormat
  bitDepth = startpump.getBits(4) + 1;
  startpump.getBits(4); // NumBlkInRCUnit
  startpump.getBits(4); // CompressionRatio
  width = startpump.getBits(16);
  height = startpump.getBits(16);
  startpump.getBits(16); // TileWidth
  startpump.getBits(4);  // reserved

  // The format includes an optimization code that sets 3 flags to change the
  // decoding parameters
  const uint32_t optflags = startpump.getBits(4);
  if (optflags > static_cast<uint32_t>(OptFlags::ALL))
    ThrowRDE("Invalid opt flags %x", optflags);
  _flags = static_cast<OptFlags>(optflags);

  startpump.getBits(8); // OverlapWidth
  startpump.getBits(8); // reserved
  startpump.getBits(8); // Inc
  startpump.getBits(2); // reserved
  initVal = startpump.getBits(14);

  assert(startpump.getPosition() == headerSize);

  if (width == 0 || height == 0 || width % 16 != 0 || width > 6496 ||
      height > 4336)
    ThrowRDE("Unexpected image dimensions found: (%i; %i)", width, height);

  if (width != mRaw->dim.x || height != mRaw->dim.y)
    ThrowRDE("EXIF image dimensions do not match dimensions from raw header");

  data = startpump.getStream(startpump.getRemainSize());
}

void SamsungV2Decompressor::decompress() {
  switch (_flags) {
  case OptFlags::NONE:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::NONE>(row);
    break;
  case OptFlags::ALL:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::ALL>(row);
    break;

  case OptFlags::SKIP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP>(row);
    break;
  case OptFlags::MV:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::MV>(row);
    break;
  case OptFlags::QP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::QP>(row);
    break;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
  case OptFlags::SKIP | OptFlags::MV:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::MV>(row);
    break;
  case OptFlags::SKIP | OptFlags::QP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::QP>(row);
    break;

  case OptFlags::MV | OptFlags::QP:
    for (int row = 0; row < height; row++)
      decompressRow<OptFlags::MV | OptFlags::QP>(row);
    break;
#pragma GCC diagnostic pop

  default:
    __builtin_unreachable();
  }
}

// The format is relatively straightforward. Each line gets encoded as a set
// of differences from pixels from another line. Pixels are grouped in blocks
// of 16 (8 green, 8 red or blue). Each block is encoded in three sections.
// First 1 or 4 bits to specify which reference pixels to use, then a section
// that specifies for each pixel the number of bits in the difference, then
// the actual difference bits

template <SamsungV2Decompressor::OptFlags optflags>
inline void SamsungV2Decompressor::prepareBaselineValues(BitPumpMSB32* pump,
                                                         int row, int col) {
  const Array2DRef<uint16_t> out(mRaw->getU16DataAsUncroppedArray2DRef());

  if (!(optflags & OptFlags::QP) && !(col & 63)) {
    static constexpr std::array<int32_t, 3> scalevals = {{0, -2, 2}};
    uint32_t i = pump->getBits(2);
    scale = i < 3 ? scale + scalevals[i] : pump->getBits(12);
  }

  // First we figure out which reference pixels mode we're in
  if (optflags & OptFlags::MV)
    motion = pump->getBits(1) ? 3 : 7;
  else if (!pump->getBits(1))
    motion = pump->getBits(3);

  if ((row == 0 || row == 1) && (motion != 7))
    ThrowRDE("At start of image and motion isn't 7. File corrupted?");

  if (motion == 7) {
    // The base case, just set all pixels to the previous ones on the same
    // line If we're at the left edge we just start at the initial value
    for (int i = 0; i < 16; i++)
      out(row, col + i) = (col == 0) ? initVal : out(row, col + i - 2);
    return;
  }

  // The complex case, we now need to actually lookup one or two lines above
  if (row < 2)
    ThrowRDE("Got a previous line lookup on first two lines. File corrupted?");

  static constexpr std::array<int32_t, 7> motionOffset = {-4, -2, -2, 0,
                                                          0,  2,  4};
  static constexpr std::array<int32_t, 7> motionDoAverage = {0, 0, 1, 0,
                                                             1, 0, 0};

  int32_t slideOffset = motionOffset[motion];
  int32_t doAverage = motionDoAverage[motion];

  for (int i = 0; i < 16; i++) {
    int refRow = row;
    int refCol = col + i + slideOffset;

    if ((row + i) & 1) { // Red or blue pixels use same color two lines up
      refRow -= 2;
    } else { // Green pixel N uses Green pixel N from row above
      refRow -= 1;
      refCol += (i & 1) ? -1 : 1; // (top left or top right)
    }

    if (refCol < 0)
      ThrowRDE("Bad motion %u at the beginning of the row", motion);
    if ((refCol >= width) || (doAverage && (refCol + 2 >= width)))
      ThrowRDE("Bad motion %u at the end of the row", motion);

    // In some cases we use as reference interpolation of this pixel and
    // the next
    if (doAverage) {
      out(row, col + i) =
          (out(refRow, refCol) + out(refRow, refCol + 2) + 1) >> 1;
    } else
      out(row, col + i) = out(refRow, refCol);
  }
}

template <SamsungV2Decompressor::OptFlags optflags>
inline std::array<uint32_t, 4>
SamsungV2Decompressor::decodeDiffLengths(BitPumpMSB32* pump, int row) {
  if (!(optflags & OptFlags::SKIP || !pump->getBits(1)))
    return {};

  std::array<uint32_t, 4> diffBits;

  // Figure out how many difference bits we have to read for each pixel
  std::array<uint32_t, 4> flags;
  for (unsigned int& flag : flags)
    flag = pump->getBits(2);

  for (int i = 0; i < 4; i++) {
    // The color is 0-Green 1-Blue 2-Red
    uint32_t colornum = (row % 2 != 0) ? i >> 1 : ((i >> 1) + 2) % 3;

    assert(flags[i] <= 3);
    switch (flags[i]) {
    case 0:
      diffBits[i] = diffBitsMode[colornum][0];
      break;
    case 1:
      diffBits[i] = diffBitsMode[colornum][0] + 1;
      break;
    case 2:
      if (diffBitsMode[colornum][0] == 0)
        ThrowRDE("Difference bits underflow. File corrupted?");
      diffBits[i] = diffBitsMode[colornum][0] - 1;
      break;
    case 3:
      diffBits[i] = pump->getBits(4);
      break;
    default:
      __builtin_unreachable();
    }

    diffBitsMode[colornum][0] = diffBitsMode[colornum][1];
    diffBitsMode[colornum][1] = diffBits[i];

    if (diffBits[i] > bitDepth + 1)
      ThrowRDE("Too many difference bits. File corrupted?");
  }

  return diffBits;
}

template <SamsungV2Decompressor::OptFlags optflags>
inline std::array<int, 16>
SamsungV2Decompressor::decodeDifferences(BitPumpMSB32* pump, int row) {
  std::array<int, 16> diffs;

  // Figure out how many difference bits we have to read for each pixel
  const std::array<uint32_t, 4> diffBits =
      decodeDiffLengths<optflags>(pump, row);

  // Actually read the differences and reshuffle them.
  for (int i = 0; i < 16; i++) {
    uint32_t len = diffBits[i >> 2];
    int32_t diff = getDiff(pump, len);

    int p;
    // The differences are stored interlaced:
    // 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
    if (row % 2)
      p = ((i % 8) << 1) - (i >> 3) + 1;
    else
      p = ((i % 8) << 1) + (i >> 3);

    diffs[p] = diff * (scale * 2 + 1) + scale;
  }

  return diffs;
}

template <SamsungV2Decompressor::OptFlags optflags>
void SamsungV2Decompressor::decompressRow(int row) {
  const Array2DRef<uint16_t> out(mRaw->getU16DataAsUncroppedArray2DRef());

  // Align pump to 16byte boundary
  const auto line_offset = data.getPosition();
  if ((line_offset & 0xf) != 0)
    data.skipBytes(16 - (line_offset & 0xf));

  BitPumpMSB32 pump(data);

  // Initialize the motion and diff modes at the start of the line
  motion = 7;
  // By default we are not scaling values at all
  scale = 0;

  for (auto& i : diffBitsMode)
    i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;

  assert(width >= 16);
  assert(width % 16 == 0);
  for (int col = 0; col < width; col += 16) {
    prepareBaselineValues<optflags>(&pump, row, col);

    // Figure out how many difference bits we have to read for each pixel
    const std::array<int, 16> diffs = decodeDifferences<optflags>(&pump, row);

    // Actually apply the differences and write them to the pixels
    for (int i = 0; i < 16; i++) {
      int diff = diffs[i];

      uint16_t& pixel = out(row, col + i);
      pixel = clampBits(static_cast<int>(pixel) + diff, bits);
    }
  }

  data.skipBytes(pump.getBufferPosition());
}

} // namespace rawspeed
<|endoftext|>


<commit_before><commit_msg>Unary functor classes<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: anim.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: cl $ $Date: 2001-02-07 16:22:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_ANIM_HXX
#define _XMLOFF_ANIM_HXX

#ifndef _COM_SUN_STAR_PRESENTATION_ANIMATIONEFFECT_HPP_
#include <com/sun/star/presentation/AnimationEffect.hpp>
#endif

#ifndef _COM_SUN_STAR_DRAWING_XSHAPE_HPP_
#include <com/sun/star/drawing/XShape.hpp>
#endif

#ifndef _UNIVERSALL_REFERENCE_HXX
#include <uniref.hxx>
#endif

#ifndef _XMLOFF_XMLEMENT_HXX
#include "xmlement.hxx"
#endif

enum XMLEffect
{
    EK_none,
    EK_fade,
    EK_move,
    EK_stripes,
    EK_open,
    EK_close,
    EK_dissolve,
    EK_wavyline,
    EK_random,
    EK_lines,
    EK_laser,
    EK_appear,
    EK_hide,
    EK_move_short,
    EK_checkerboard,
    EK_rotate,
    EK_stretch
};

extern SvXMLEnumMapEntry aXML_AnimationEffect_EnumMap[];

enum XMLEffectDirection
{
    ED_none,
    ED_from_left,
    ED_from_top,
    ED_from_right,
    ED_from_bottom,
    ED_from_center,
    ED_from_upperleft,
    ED_from_upperright,
    ED_from_lowerleft,
    ED_from_lowerright,

    ED_to_left,
    ED_to_top,
    ED_to_right,
    ED_to_bottom,
    ED_to_upperleft,
    ED_to_upperright,
    ED_to_lowerright,
    ED_to_lowerleft,

    ED_path,
    ED_spiral_inward_left,
    ED_spiral_inward_right,
    ED_spiral_outward_left,
    ED_spiral_outward_right,

    ED_vertical,
    ED_horizontal,

    ED_to_center,

    ED_clockwise,
    ED_cclockwise
};

extern SvXMLEnumMapEntry aXML_AnimationDirection_EnumMap[];

extern SvXMLEnumMapEntry aXML_AnimationSpeed_EnumMap[];

void SdXMLImplSetEffect( ::com::sun::star::presentation::AnimationEffect eEffect, XMLEffect& eKind, XMLEffectDirection& eDirection, sal_Int16& nStartScale, sal_Bool& bIn );
::com::sun::star::presentation::AnimationEffect ImplSdXMLgetEffect( XMLEffect eKind, XMLEffectDirection eDirection, sal_Int16 nStartScale, sal_Bool bIn );

#endif  //  _XMLOFF_ANIM_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.644); FILE MERGED 2005/09/05 14:38:02 rt 1.3.644.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: anim.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:02:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_ANIM_HXX
#define _XMLOFF_ANIM_HXX

#ifndef _COM_SUN_STAR_PRESENTATION_ANIMATIONEFFECT_HPP_
#include <com/sun/star/presentation/AnimationEffect.hpp>
#endif

#ifndef _COM_SUN_STAR_DRAWING_XSHAPE_HPP_
#include <com/sun/star/drawing/XShape.hpp>
#endif

#ifndef _UNIVERSALL_REFERENCE_HXX
#include <uniref.hxx>
#endif

#ifndef _XMLOFF_XMLEMENT_HXX
#include "xmlement.hxx"
#endif

enum XMLEffect
{
    EK_none,
    EK_fade,
    EK_move,
    EK_stripes,
    EK_open,
    EK_close,
    EK_dissolve,
    EK_wavyline,
    EK_random,
    EK_lines,
    EK_laser,
    EK_appear,
    EK_hide,
    EK_move_short,
    EK_checkerboard,
    EK_rotate,
    EK_stretch
};

extern SvXMLEnumMapEntry aXML_AnimationEffect_EnumMap[];

enum XMLEffectDirection
{
    ED_none,
    ED_from_left,
    ED_from_top,
    ED_from_right,
    ED_from_bottom,
    ED_from_center,
    ED_from_upperleft,
    ED_from_upperright,
    ED_from_lowerleft,
    ED_from_lowerright,

    ED_to_left,
    ED_to_top,
    ED_to_right,
    ED_to_bottom,
    ED_to_upperleft,
    ED_to_upperright,
    ED_to_lowerright,
    ED_to_lowerleft,

    ED_path,
    ED_spiral_inward_left,
    ED_spiral_inward_right,
    ED_spiral_outward_left,
    ED_spiral_outward_right,

    ED_vertical,
    ED_horizontal,

    ED_to_center,

    ED_clockwise,
    ED_cclockwise
};

extern SvXMLEnumMapEntry aXML_AnimationDirection_EnumMap[];

extern SvXMLEnumMapEntry aXML_AnimationSpeed_EnumMap[];

void SdXMLImplSetEffect( ::com::sun::star::presentation::AnimationEffect eEffect, XMLEffect& eKind, XMLEffectDirection& eDirection, sal_Int16& nStartScale, sal_Bool& bIn );
::com::sun::star::presentation::AnimationEffect ImplSdXMLgetEffect( XMLEffect eKind, XMLEffectDirection eDirection, sal_Int16 nStartScale, sal_Bool bIn );

#endif  //  _XMLOFF_ANIM_HXX

<|endoftext|>


<commit_before>#include "sugarcrmresource.h"
#include "sugarsoap.h"
#include "sugarconfig.h"

#include "settings.h"
#include "settingsadaptor.h"

#include <QtDBus/QDBusConnection>

#include <KWindowSystem>
#include <KABC/Addressee>
#include <Akonadi/ItemFetchScope>
#include <Akonadi/ChangeRecorder>
#include <KLocalizedString>

using namespace Akonadi;

SugarCrmResource::SugarCrmResource( const QString &id )
  : ResourceBase( id )
{
  // Populate Map of valid modules and required fields for each module
  module *modinfo = new module;
  modinfo->fields << "first_name" << "last_name" << "email1";
  modinfo->mimes << "text/directory";
  SugarCrmResource::Modules["Contacts"] = SugarCrmResource::Modules["Leads"] = *modinfo;

  modinfo = new module;
  modinfo->fields << "name" << "description" << "date_due_flag" << "date_due" << "date_start_flag" << "date_start";
  modinfo->mimes << "text/calendar";
  SugarCrmResource::Modules["Tasks"] = *modinfo;

  modinfo = new module;
  modinfo->fields << "name" << "description" << "case_number" << "date_due" << "date_start_flag" << "date_start";
  modinfo->mimes << "application/x-vnd.akonadi.calendar.todo";
  // TODO: where status is active
  SugarCrmResource::Modules["Cases"] = *modinfo;

  new SettingsAdaptor( Settings::self() );
  QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ),
                            Settings::self(), QDBusConnection::ExportAdaptors );

  changeRecorder()->itemFetchScope().fetchFullPayload();
}

SugarCrmResource::~SugarCrmResource()
{
}

void SugarCrmResource::retrieveCollections()
{
  KUrl url = KUrl(Settings::self()->url());
  if (!url.hasUser()) url.setUser(Settings::self()->username());

  Collection c;
  c.setParent(Collection::root());
  c.setRemoteId(url.url());
  c.setName(i18n("SugarCRM resource for %1").arg(url.url()));

  QStringList mimeTypes;
  mimeTypes << QLatin1String("text/directory");
  c.setContentMimeTypes(mimeTypes);

  Collection::List list;
  list << c;
  collectionsRetrieved(list);
}

void SugarCrmResource::retrieveItems( const Akonadi::Collection &collection )
{
  Q_UNUSED(collection);
  soap = new SugarSoap(Settings::self()->url().url());
  QStringList *soapItems = soap->getEntries("Contacts");;

  Item::List items;
  foreach (QString itemId, (*soapItems))
  {
    Item item("text/directory");
    item.setRemoteId(itemId);
    items << item;
  }

  itemsRetrieved( items );
}

bool SugarCrmResource::retrieveItem( const Akonadi::Item &item, const QSet<QByteArray> &parts )
{
  Q_UNUSED( parts );

  soap = new SugarSoap(Settings::self()->url().url());
  // TODO check returned value
  QHash<QString, QString> *rawItem = soap->getEntry("Contacts", item.remoteId());

  KABC::Addressee addressee;
  addressee.setGivenName((*rawItem)["first_name"]);
  addressee.setFamilyName((*rawItem)["last_name"]);
  QStringList emails;
  emails << (*rawItem)["email1"];
  addressee.setEmails(emails);
  Item newItem( item );
  newItem.setPayload<KABC::Addressee>( addressee );
  itemRetrieved( newItem );
  return true;
}

void SugarCrmResource::aboutToQuit()
{
  // TODO: any cleanup you need to do while there is still an active
  // event loop. The resource will terminate after this method returns
}

void SugarCrmResource::configure( WId windowId )
{
  Q_UNUSED( windowId );

  // TODO: populate form fields
  KWindowSystem::setMainWindow(&configDlg, windowId);

  if (configDlg.exec() == QDialog::Rejected)
  {
    emit configurationDialogRejected();
    return;
  }

  soap = new SugarSoap(configDlg.url());
  // TODO timeout
  Settings::self()->setSessionId(soap->login(configDlg.username(), configDlg.password()));
  if (Settings::self()->sessionId().isEmpty())
  {
    emit configurationDialogRejected();
    return;
  }

  Settings::self()->setUrl(configDlg.url());
  Settings::self()->setUsername(configDlg.username());
  Settings::self()->setPassword(configDlg.password());

  Settings::self()->writeConfig();

  emit configurationDialogAccepted();

  synchronize();
}

void SugarCrmResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
{
  Q_UNUSED(item);
  Q_UNUSED(collection);
}

void SugarCrmResource::itemChanged( const Akonadi::Item &item, const QSet<QByteArray> &parts )
{
  Q_UNUSED(item);
  Q_UNUSED(parts);
}

void SugarCrmResource::itemRemoved( const Akonadi::Item &item )
{
  Q_UNUSED(item);
}

AKONADI_RESOURCE_MAIN( SugarCrmResource );
QHash<QString,module> SugarCrmResource::Modules;

#include "sugarcrmresource.moc"
<commit_msg>Fetch Leads as well as contacts for address books.<commit_after>#include "sugarcrmresource.h"
#include "sugarsoap.h"
#include "sugarconfig.h"

#include "settings.h"
#include "settingsadaptor.h"

#include <QtDBus/QDBusConnection>

#include <KWindowSystem>
#include <KABC/Addressee>
#include <Akonadi/ItemFetchScope>
#include <Akonadi/ChangeRecorder>
#include <KLocalizedString>

using namespace Akonadi;

SugarCrmResource::SugarCrmResource( const QString &id )
  : ResourceBase( id )
{
  // Populate Map of valid modules and required fields for each module
  module *modinfo = new module;
  modinfo->fields << "first_name" << "last_name" << "email1";
  modinfo->mimes << "text/directory";
  SugarCrmResource::Modules["Contacts"] = SugarCrmResource::Modules["Leads"] = *modinfo;

  modinfo = new module;
  modinfo->fields << "name" << "description" << "date_due_flag" << "date_due" << "date_start_flag" << "date_start";
  modinfo->mimes << "text/calendar";
  SugarCrmResource::Modules["Tasks"] = *modinfo;

  modinfo = new module;
  modinfo->fields << "name" << "description" << "case_number" << "date_due" << "date_start_flag" << "date_start";
  modinfo->mimes << "application/x-vnd.akonadi.calendar.todo";
  // TODO: where status is active
  SugarCrmResource::Modules["Cases"] = *modinfo;

  new SettingsAdaptor( Settings::self() );
  QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ),
                            Settings::self(), QDBusConnection::ExportAdaptors );

  changeRecorder()->itemFetchScope().fetchFullPayload();
}

SugarCrmResource::~SugarCrmResource()
{
}

void SugarCrmResource::retrieveCollections()
{
  KUrl url = KUrl(Settings::self()->url());
  if (!url.hasUser()) url.setUser(Settings::self()->username());

  QStringList mimeTypes;
  mimeTypes << QLatin1String("text/directory");

  Collection c;
  c.setParent(Collection::root());
  c.setRemoteId("Contacts@" + url.url());
  c.setName(i18n("Contacts from SugarCRM resource at %1").arg(url.url()));
  c.setContentMimeTypes(mimeTypes);

  Collection l;
  l.setParent(Collection::root());
  l.setRemoteId("Leads@" + url.url());
  l.setName(i18n("Leads from SugarCRM resource at %1").arg(url.url()));
  l.setContentMimeTypes(mimeTypes);

  Collection::List list;
  list << c << l;
  collectionsRetrieved(list);
}

void SugarCrmResource::retrieveItems( const Akonadi::Collection &collection )
{
  QString mod = collection.remoteId().replace(QRegExp("@.*"), "");
  if (!SugarCrmResource::Modules.contains(mod))
    return;
  soap = new SugarSoap(Settings::self()->url().url());
  QStringList *soapItems = soap->getEntries(mod);;

  Item::List items;
  foreach (QString itemId, (*soapItems))
  {
    Item item("text/directory");
    item.setRemoteId(mod + "@" + itemId);
    item.setParentCollection(collection);
    items << item;
  }

  itemsRetrieved( items );
}

bool SugarCrmResource::retrieveItem( const Akonadi::Item &item, const QSet<QByteArray> &parts )
{
  Q_UNUSED( parts );
  QString mod = item.remoteId().replace(QRegExp("@.*"), "");
  if (!SugarCrmResource::Modules.contains(mod))
    return false;

  soap = new SugarSoap(Settings::self()->url().url());
  // TODO check returned value
  QHash<QString, QString> *rawItem = soap->getEntry(mod, item.remoteId().replace(QRegExp(".*@"), ""));

  KABC::Addressee addressee;
  addressee.setGivenName((*rawItem)["first_name"]);
  addressee.setFamilyName((*rawItem)["last_name"]);
  QStringList emails;
  emails << (*rawItem)["email1"];
  addressee.setEmails(emails);
  Item newItem( item );
  newItem.setPayload<KABC::Addressee>( addressee );
  itemRetrieved( newItem );
  return true;
}

void SugarCrmResource::aboutToQuit()
{
  // TODO: any cleanup you need to do while there is still an active
  // event loop. The resource will terminate after this method returns
}

void SugarCrmResource::configure( WId windowId )
{
  Q_UNUSED( windowId );

  // TODO: populate form fields
  KWindowSystem::setMainWindow(&configDlg, windowId);

  if (configDlg.exec() == QDialog::Rejected)
  {
    emit configurationDialogRejected();
    return;
  }

  soap = new SugarSoap(configDlg.url());
  // TODO timeout
  Settings::self()->setSessionId(soap->login(configDlg.username(), configDlg.password()));
  if (Settings::self()->sessionId().isEmpty())
  {
    emit configurationDialogRejected();
    return;
  }

  Settings::self()->setUrl(configDlg.url());
  Settings::self()->setUsername(configDlg.username());
  Settings::self()->setPassword(configDlg.password());

  Settings::self()->writeConfig();

  emit configurationDialogAccepted();

  synchronize();
}

void SugarCrmResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
{
  Q_UNUSED(item);
  Q_UNUSED(collection);
}

void SugarCrmResource::itemChanged( const Akonadi::Item &item, const QSet<QByteArray> &parts )
{
  Q_UNUSED(item);
  Q_UNUSED(parts);
}

void SugarCrmResource::itemRemoved( const Akonadi::Item &item )
{
  Q_UNUSED(item);
}

AKONADI_RESOURCE_MAIN( SugarCrmResource );
QHash<QString,module> SugarCrmResource::Modules;

#include "sugarcrmresource.moc"
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: txenctab.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2004-01-06 15:19:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_TXENCTAB_HXX
#define _SVX_TXENCTAB_HXX

// include ---------------------------------------------------------------

#ifndef _RESARY_HXX //autogen
#include <tools/resary.hxx>
#endif
#ifndef _RTL_TEXTENC_H
#include <rtl/textenc.h>
#endif

//========================================================================
//  class SvxTextEncodingTable
//========================================================================

class SvxTextEncodingTable : public ResStringArray
{
public:
    SvxTextEncodingTable();
    ~SvxTextEncodingTable();

    const String&       GetTextString( const rtl_TextEncoding nEnc ) const;
    rtl_TextEncoding    GetTextEncoding( const String& rStr ) const;
};

#endif

<commit_msg>INTEGRATION: CWS visibility01 (1.2.462); FILE MERGED 2004/12/06 08:10:52 mnicel 1.2.462.1: Part of symbol visibility markup - #i35758#<commit_after>/*************************************************************************
 *
 *  $RCSfile: txenctab.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 15:40:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_TXENCTAB_HXX
#define _SVX_TXENCTAB_HXX

// include ---------------------------------------------------------------

#ifndef _RESARY_HXX //autogen
#include <tools/resary.hxx>
#endif
#ifndef _RTL_TEXTENC_H
#include <rtl/textenc.h>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

//========================================================================
//  class SvxTextEncodingTable
//========================================================================

class SVX_DLLPUBLIC SvxTextEncodingTable : public ResStringArray
{
public:
    SvxTextEncodingTable();
    ~SvxTextEncodingTable();

    const String&       GetTextString( const rtl_TextEncoding nEnc ) const;
    rtl_TextEncoding    GetTextEncoding( const String& rStr ) const;
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xlinjoit.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:34:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SVX_XLINJOIT_HXX
#define _SVX_XLINJOIT_HXX

#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _XENUM_HXX
#include <svx/xenum.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

//---------------------
// class LineStyleItem
//---------------------

class SVX_DLLPUBLIC XLineJointItem : public SfxEnumItem
{
public:
                            TYPEINFO();
                            XLineJointItem( XLineJoint eLineJoint = XLINEJOINT_ROUND );
                            XLineJointItem( SvStream& rIn );

    virtual USHORT           GetVersion( USHORT nFileFormatVersion ) const;
    virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const;
    virtual SfxPoolItem*    Create( SvStream& rIn, USHORT nVer ) const;

    virtual sal_Bool             QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
    virtual sal_Bool             PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );
    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric,
                                    String &rText, const IntlWrapper * = 0 ) const;

    virtual USHORT          GetValueCount() const;
    XLineJoint              GetValue() const { return (XLineJoint) SfxEnumItem::GetValue(); }
};

#endif // _SVX_XLINJOIT_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.5.368); FILE MERGED 2008/04/01 15:49:26 thb 1.5.368.3: #i85898# Stripping all external header guards 2008/04/01 12:46:30 thb 1.5.368.2: #i85898# Stripping all external header guards 2008/03/31 14:18:02 rt 1.5.368.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: xlinjoit.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SVX_XLINJOIT_HXX
#define _SVX_XLINJOIT_HXX

#include <svtools/eitem.hxx>
#include <svx/xenum.hxx>
#include "svx/svxdllapi.h"

//---------------------
// class LineStyleItem
//---------------------

class SVX_DLLPUBLIC XLineJointItem : public SfxEnumItem
{
public:
                            TYPEINFO();
                            XLineJointItem( XLineJoint eLineJoint = XLINEJOINT_ROUND );
                            XLineJointItem( SvStream& rIn );

    virtual USHORT           GetVersion( USHORT nFileFormatVersion ) const;
    virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const;
    virtual SfxPoolItem*    Create( SvStream& rIn, USHORT nVer ) const;

    virtual sal_Bool             QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
    virtual sal_Bool             PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );
    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric,
                                    String &rText, const IntlWrapper * = 0 ) const;

    virtual USHORT          GetValueCount() const;
    XLineJoint              GetValue() const { return (XLineJoint) SfxEnumItem::GetValue(); }
};

#endif // _SVX_XLINJOIT_HXX
<|endoftext|>


<commit_before>
#include <string.h>
#include "atXMLBuffer.h++"

atXMLBuffer::atXMLBuffer(char * xmlName)
{
   // Save the header and footer for this overall XML document
   sprintf(xml_header, "<%s>", xmlName);
   sprintf(xml_footer, "</%s>", xmlName);

   // Initialize the internal XML buffer length
   xml_buffer_size = 0;

   // Initialize the xml DTD (we aren't using one in this case and also
   // don't need a context then)
   xml_dtd = NULL;

   // Initialize the documents buffer (we will collect any documents
   // from the XML elements into this list and send them back)
   xml_document_list = new atList();
}

atXMLBuffer::atXMLBuffer(char * xmlName, char * dtdFilename)
{
   // Save the header and footer for this overall XML document
   sprintf((char *) xml_header, "<%s>", xmlName);
   sprintf((char *) xml_footer, "</%s>", xmlName);

   // Initialize the internal XML buffer length
   xml_buffer_size = 0;

   // Open and initialize the DTD file (used for validating XML)
   xml_dtd = xmlParseDTD(NULL, (const xmlChar *) dtdFilename);

   // Initialize the XML context information (used during XML validation
   // to print warnings and errors)
   xml_context.userData = stderr;
   xml_context.error = (xmlValidityErrorFunc ) fprintf;
   xml_context.warning = (xmlValidityWarningFunc ) fprintf;

   // Initialize the documents buffer (we will collect any documents
   // from the XML elements into this list and send them back)
   xml_document_list = new atList();
}

atXMLBuffer::~atXMLBuffer()
{
   // Free up the DTD if we created it
   if (xml_dtd != NULL)
      xmlFreeDtd(xml_dtd);

   // Free up XML document list
   if (xml_document_list != NULL)
      delete xml_document_list;
}

void atXMLBuffer::processXMLDocument()
{
   xmlDocPtr         doc;
   xmlNodePtr        current;
   char              fullHeader[256];
   xmlChar *         version;
   atXMLDocument *   xmlDoc;

   // Open the memory buffer as an XML document
   doc = xmlParseMemory((const char *) xml_buffer, xml_buffer_size);

   // Check to make sure the XML library understood the buffer
   if (doc == NULL)
   {
      // We didn't recognize the XML at all so warn the user and bail out
      notify(AT_WARN, "XML document not parsed successfully.\n");
      xmlFreeDoc(doc);
      return;
   }

   // Check to see if we're checking the XML against the DTD
   if (xml_dtd != NULL)
   {
      // We are so go ahead and validate the XML against the DTD
      if (xmlValidateDtd(&xml_context, doc, xml_dtd) == 0)
      {
         // The document failed the DTD check so warn the user and bail out
         notify(AT_WARN, "XML document not valid.\n");
         xmlFreeDoc(doc);
         return;
      }
   }

   // Ok, now let's get the XML root element (all non-empty XML documents
   // have a root)
   current = xmlDocGetRootElement(doc);

   // Check to see if we got something in the root (i.e. it's not an
   // empty document)
   if (current == NULL)
   {
      notify(AT_WARN, "XML document is empty.\n");
      xmlFreeDoc(doc);
      return;
   }

   // Now, check to make sure the root element is the header
   // (all XML documents start with the header and end with the footer
   sprintf(fullHeader, "<%s>", current->name);
   if (xmlStrcmp((xmlChar *) fullHeader, (xmlChar *) xml_header))
   {
      notify(AT_WARN, "XML document is of wrong type.\n");
      xmlFreeDoc(doc);
      return;
   }

   // Get the version of XML we're using from the header
   // (later on, we'll assume that NULL means 1.0)
   version = xmlGetProp(current, (const xmlChar *) "version");

   // The document is "certified" so add the document to the document list
   xmlDoc = new atXMLDocument((atXMLDocumentDocPtr ) doc);
   xml_document_list->addEntry(xmlDoc);

   // We're done so free the stuff we're required to free ourselves.  We
   // added the document itself to the list so we'll assume it's deallocated
   // later.
   xmlFree(version);
}

atList * atXMLBuffer::processBuffer(atBufferHandler * packetBuffer)
{
   u_char *   buffer;
   u_long     lengthRead;
   u_char *   nextNull;
   u_char *   newBuffer;
   atItem *   item;
   u_char *   endTag;
   int        partialChunkSize;
   u_long     numWhiteSpace;

   // Get the info from this buffer
   packetBuffer->retrieveBuffer(&buffer, &lengthRead);

   // Go through and eradicate NULL characters (the XML library will
   // consider it the end of the document)
   nextNull = (u_char *) memchr(buffer, '\0', lengthRead);
   while (nextNull != NULL)
   {
      // Slide the buffer up one to get rid of this NULL
      memmove(nextNull, nextNull+1, lengthRead - (nextNull - buffer));
      lengthRead--;

      // Find the next NULL
      nextNull = (u_char *) memchr(buffer, '\0', lengthRead);
   }

   // Allocate a buffer to hold this buffer and left over from the last pass
   newBuffer = (u_char *) calloc(xml_buffer_size+lengthRead+1, sizeof(u_char));
   if (newBuffer == NULL)
   {
      // We failed to allocate space (bad!) so assume we have nothing
      notify(AT_WARN, "Failed to allocate space for combining buffers.\n");
      lengthRead = 0;
   }
   else
   {
      // Stick any partial buffer that was saved last go around in front
      // of the new buffer (this is necessary to cover the case when the
      // end tag footer gets split between packets)
      memcpy(newBuffer, xml_buffer, xml_buffer_size);
      memcpy(&newBuffer[xml_buffer_size], buffer, lengthRead);
      lengthRead += xml_buffer_size;
      xml_buffer_size = 0;
   }

   // Make a string out of the buffer
   newBuffer[lengthRead] = '\0';

   // We will build up each recognized XML document and add it to a list
   // to return to the user so we need to clear it first (so go through
   // each list item in the list now and remove it)
   item = xml_document_list->getFirstEntry();
   while (item != NULL)
   {
      // Remove this list item
      xml_document_list->removeCurrentEntry();

      // Delete this list item to free up the memory since we're done
      // with it
      delete item;

      // Get the first node again (if there is one)
      item = xml_document_list->getFirstEntry();
   }

   // Check if we see the ending footer
   endTag = (u_char *) strstr((const char *) newBuffer, xml_footer);
   if (endTag != NULL)
   {
      // We need to loop in case there are multiple documents within
      // the buffer
      while (endTag != NULL)
      {
         // Copy through the ending footer to the internal
         // collected xml buffer
         partialChunkSize = (int ) (endTag - &newBuffer[0]) +
                            (int ) strlen(xml_footer);
         memcpy(&xml_buffer[xml_buffer_size], newBuffer, partialChunkSize);
         xml_buffer_size += partialChunkSize;

         // Delete the part we just used (+1 for the NULL we tacked on)
         memmove(&newBuffer[0], &newBuffer[partialChunkSize],
                 lengthRead - partialChunkSize + 1);
         lengthRead -= partialChunkSize;

         // Eliminate any leading white space lines left in the buffer
         numWhiteSpace = (u_long ) strspn((const char *) newBuffer, " \r\n\t");
         if ( (numWhiteSpace > 0) && (numWhiteSpace <= lengthRead) )
         {
            // Move up the remaining part of the buffer (+1 for the NULL
            // we tacked on)
            memmove(&newBuffer[0], &newBuffer[numWhiteSpace],
                    (lengthRead - numWhiteSpace + 1) * sizeof(u_char));
            lengthRead -= numWhiteSpace;
         }

         // Process the document
         processXMLDocument();

         // Clear the internal xml buffer
         xml_buffer_size = 0;

         // See if there is another footer (in case there are two
         // or more within the buffer)
         endTag = (u_char *) strstr((const char *) newBuffer, xml_footer);
      }

      // Store remaining chunk (if any) in internal collected xml buffer
      if (lengthRead > 0)
      {
         // Copy remaining chunk into xml buffer and initialize
         // size to size of that remaining chunk
         memcpy(&xml_buffer[0], &newBuffer[0], lengthRead);
         xml_buffer_size = lengthRead;
      }
      else
      {
         // Nothing left in buffer so just initialize xml buffer
         xml_buffer[0] = '\0';
         xml_buffer_size = 0;
      }
   }
   else
   {
      // No ending found so just add what we received to the
      // internal collected xml buffer
      memcpy(&xml_buffer[xml_buffer_size], newBuffer, lengthRead);
      xml_buffer_size += lengthRead;
   }

   // Free the temporary buffer
   if (newBuffer != NULL)
      free(newBuffer);

   // Return the list of documents that were collected
   return xml_document_list;
}

<commit_msg>Don't free a NULL!<commit_after>
#include <string.h>
#include "atXMLBuffer.h++"

atXMLBuffer::atXMLBuffer(char * xmlName)
{
   // Save the header and footer for this overall XML document
   sprintf(xml_header, "<%s>", xmlName);
   sprintf(xml_footer, "</%s>", xmlName);

   // Initialize the internal XML buffer length
   xml_buffer_size = 0;

   // Initialize the xml DTD (we aren't using one in this case and also
   // don't need a context then)
   xml_dtd = NULL;

   // Initialize the documents buffer (we will collect any documents
   // from the XML elements into this list and send them back)
   xml_document_list = new atList();
}

atXMLBuffer::atXMLBuffer(char * xmlName, char * dtdFilename)
{
   // Save the header and footer for this overall XML document
   sprintf((char *) xml_header, "<%s>", xmlName);
   sprintf((char *) xml_footer, "</%s>", xmlName);

   // Initialize the internal XML buffer length
   xml_buffer_size = 0;

   // Open and initialize the DTD file (used for validating XML)
   xml_dtd = xmlParseDTD(NULL, (const xmlChar *) dtdFilename);

   // Initialize the XML context information (used during XML validation
   // to print warnings and errors)
   xml_context.userData = stderr;
   xml_context.error = (xmlValidityErrorFunc ) fprintf;
   xml_context.warning = (xmlValidityWarningFunc ) fprintf;

   // Initialize the documents buffer (we will collect any documents
   // from the XML elements into this list and send them back)
   xml_document_list = new atList();
}

atXMLBuffer::~atXMLBuffer()
{
   // Free up the DTD if we created it
   if (xml_dtd != NULL)
      xmlFreeDtd(xml_dtd);

   // Free up XML document list
   if (xml_document_list != NULL)
      delete xml_document_list;
}

void atXMLBuffer::processXMLDocument()
{
   xmlDocPtr         doc;
   xmlNodePtr        current;
   char              fullHeader[256];
   xmlChar *         version;
   atXMLDocument *   xmlDoc;

   // Open the memory buffer as an XML document
   doc = xmlParseMemory((const char *) xml_buffer, xml_buffer_size);

   // Check to make sure the XML library understood the buffer
   if (doc == NULL)
   {
      // We didn't recognize the XML at all so warn the user and bail out
      notify(AT_WARN, "XML document not parsed successfully.\n");
      return;
   }

   // Check to see if we're checking the XML against the DTD
   if (xml_dtd != NULL)
   {
      // We are so go ahead and validate the XML against the DTD
      if (xmlValidateDtd(&xml_context, doc, xml_dtd) == 0)
      {
         // The document failed the DTD check so warn the user and bail out
         notify(AT_WARN, "XML document not valid.\n");
         xmlFreeDoc(doc);
         return;
      }
   }

   // Ok, now let's get the XML root element (all non-empty XML documents
   // have a root)
   current = xmlDocGetRootElement(doc);

   // Check to see if we got something in the root (i.e. it's not an
   // empty document)
   if (current == NULL)
   {
      notify(AT_WARN, "XML document is empty.\n");
      xmlFreeDoc(doc);
      return;
   }

   // Now, check to make sure the root element is the header
   // (all XML documents start with the header and end with the footer
   sprintf(fullHeader, "<%s>", current->name);
   if (xmlStrcmp((xmlChar *) fullHeader, (xmlChar *) xml_header))
   {
      notify(AT_WARN, "XML document is of wrong type.\n");
      xmlFreeDoc(doc);
      return;
   }

   // Get the version of XML we're using from the header
   // (later on, we'll assume that NULL means 1.0)
   version = xmlGetProp(current, (const xmlChar *) "version");

   // The document is "certified" so add the document to the document list
   xmlDoc = new atXMLDocument((atXMLDocumentDocPtr ) doc);
   xml_document_list->addEntry(xmlDoc);

   // We're done so free the stuff we're required to free ourselves.  We
   // added the document itself to the list so we'll assume it's deallocated
   // later.
   xmlFree(version);
}

atList * atXMLBuffer::processBuffer(atBufferHandler * packetBuffer)
{
   u_char *   buffer;
   u_long     lengthRead;
   u_char *   nextNull;
   u_char *   newBuffer;
   atItem *   item;
   u_char *   endTag;
   int        partialChunkSize;
   u_long     numWhiteSpace;

   // Get the info from this buffer
   packetBuffer->retrieveBuffer(&buffer, &lengthRead);

   // Go through and eradicate NULL characters (the XML library will
   // consider it the end of the document)
   nextNull = (u_char *) memchr(buffer, '\0', lengthRead);
   while (nextNull != NULL)
   {
      // Slide the buffer up one to get rid of this NULL
      memmove(nextNull, nextNull+1, lengthRead - (nextNull - buffer));
      lengthRead--;

      // Find the next NULL
      nextNull = (u_char *) memchr(buffer, '\0', lengthRead);
   }

   // Allocate a buffer to hold this buffer and left over from the last pass
   newBuffer = (u_char *) calloc(xml_buffer_size+lengthRead+1, sizeof(u_char));
   if (newBuffer == NULL)
   {
      // We failed to allocate space (bad!) so assume we have nothing
      notify(AT_WARN, "Failed to allocate space for combining buffers.\n");
      lengthRead = 0;
   }
   else
   {
      // Stick any partial buffer that was saved last go around in front
      // of the new buffer (this is necessary to cover the case when the
      // end tag footer gets split between packets)
      memcpy(newBuffer, xml_buffer, xml_buffer_size);
      memcpy(&newBuffer[xml_buffer_size], buffer, lengthRead);
      lengthRead += xml_buffer_size;
      xml_buffer_size = 0;
   }

   // Make a string out of the buffer
   newBuffer[lengthRead] = '\0';

   // We will build up each recognized XML document and add it to a list
   // to return to the user so we need to clear it first (so go through
   // each list item in the list now and remove it)
   item = xml_document_list->getFirstEntry();
   while (item != NULL)
   {
      // Remove this list item
      xml_document_list->removeCurrentEntry();

      // Delete this list item to free up the memory since we're done
      // with it
      delete item;

      // Get the first node again (if there is one)
      item = xml_document_list->getFirstEntry();
   }

   // Check if we see the ending footer
   endTag = (u_char *) strstr((const char *) newBuffer, xml_footer);
   if (endTag != NULL)
   {
      // We need to loop in case there are multiple documents within
      // the buffer
      while (endTag != NULL)
      {
         // Copy through the ending footer to the internal
         // collected xml buffer
         partialChunkSize = (int ) (endTag - &newBuffer[0]) +
                            (int ) strlen(xml_footer);
         memcpy(&xml_buffer[xml_buffer_size], newBuffer, partialChunkSize);
         xml_buffer_size += partialChunkSize;

         // Delete the part we just used (+1 for the NULL we tacked on)
         memmove(&newBuffer[0], &newBuffer[partialChunkSize],
                 lengthRead - partialChunkSize + 1);
         lengthRead -= partialChunkSize;

         // Eliminate any leading white space lines left in the buffer
         numWhiteSpace = (u_long ) strspn((const char *) newBuffer, " \r\n\t");
         if ( (numWhiteSpace > 0) && (numWhiteSpace <= lengthRead) )
         {
            // Move up the remaining part of the buffer (+1 for the NULL
            // we tacked on)
            memmove(&newBuffer[0], &newBuffer[numWhiteSpace],
                    (lengthRead - numWhiteSpace + 1) * sizeof(u_char));
            lengthRead -= numWhiteSpace;
         }

         // Process the document
         processXMLDocument();

         // Clear the internal xml buffer
         xml_buffer_size = 0;

         // See if there is another footer (in case there are two
         // or more within the buffer)
         endTag = (u_char *) strstr((const char *) newBuffer, xml_footer);
      }

      // Store remaining chunk (if any) in internal collected xml buffer
      if (lengthRead > 0)
      {
         // Copy remaining chunk into xml buffer and initialize
         // size to size of that remaining chunk
         memcpy(&xml_buffer[0], &newBuffer[0], lengthRead);
         xml_buffer_size = lengthRead;
      }
      else
      {
         // Nothing left in buffer so just initialize xml buffer
         xml_buffer[0] = '\0';
         xml_buffer_size = 0;
      }
   }
   else
   {
      // No ending found so just add what we received to the
      // internal collected xml buffer
      memcpy(&xml_buffer[xml_buffer_size], newBuffer, lengthRead);
      xml_buffer_size += lengthRead;
   }

   // Free the temporary buffer
   if (newBuffer != NULL)
      free(newBuffer);

   // Return the list of documents that were collected
   return xml_document_list;
}

<|endoftext|>