| Index: src/images/bmpdecoderhelper.cpp
 | 
| diff --git a/src/images/bmpdecoderhelper.cpp b/src/images/bmpdecoderhelper.cpp
 | 
| deleted file mode 100644
 | 
| index 9171b5d5278410592db36c7e82d7170d9b90ca02..0000000000000000000000000000000000000000
 | 
| --- a/src/images/bmpdecoderhelper.cpp
 | 
| +++ /dev/null
 | 
| @@ -1,369 +0,0 @@
 | 
| -
 | 
| -/*
 | 
| - * Copyright 2007 The Android Open Source Project
 | 
| - *
 | 
| - * Use of this source code is governed by a BSD-style license that can be
 | 
| - * found in the LICENSE file.
 | 
| - */
 | 
| -
 | 
| -// Author: cevans@google.com (Chris Evans)
 | 
| -
 | 
| -#include "bmpdecoderhelper.h"
 | 
| -
 | 
| -namespace image_codec {
 | 
| -
 | 
| -static const int kBmpHeaderSize = 14;
 | 
| -static const int kBmpInfoSize = 40;
 | 
| -static const int kBmpOS2InfoSize = 12;
 | 
| -static const int kMaxDim = SHRT_MAX / 2;
 | 
| -
 | 
| -bool BmpDecoderHelper::DecodeImage(const char* p,
 | 
| -                                   size_t len,
 | 
| -                                   int max_pixels,
 | 
| -                                   BmpDecoderCallback* callback) {
 | 
| -  data_ = reinterpret_cast<const uint8*>(p);
 | 
| -  pos_ = 0;
 | 
| -  len_ = len;
 | 
| -  inverted_ = true;
 | 
| -  // Parse the header structure.
 | 
| -  if (len < kBmpHeaderSize + 4) {
 | 
| -    return false;
 | 
| -  }
 | 
| -  GetShort();  // Signature.
 | 
| -  GetInt();  // Size.
 | 
| -  GetInt();  // Reserved.
 | 
| -  int offset = GetInt();
 | 
| -  // Parse the info structure.
 | 
| -  int infoSize = GetInt();
 | 
| -  if (infoSize != kBmpOS2InfoSize && infoSize < kBmpInfoSize) {
 | 
| -    return false;
 | 
| -  }
 | 
| -  int cols = 0;
 | 
| -  int comp = 0;
 | 
| -  int colLen = 4;
 | 
| -  if (infoSize >= kBmpInfoSize) {
 | 
| -    if (len < kBmpHeaderSize + kBmpInfoSize) {
 | 
| -      return false;
 | 
| -    }
 | 
| -    width_ = GetInt();
 | 
| -    height_ = GetInt();
 | 
| -    GetShort();  // Planes.
 | 
| -    bpp_ = GetShort();
 | 
| -    comp = GetInt();
 | 
| -    GetInt();  // Size.
 | 
| -    GetInt();  // XPPM.
 | 
| -    GetInt();  // YPPM.
 | 
| -    cols = GetInt();
 | 
| -    GetInt();  // Important colours.
 | 
| -  } else {
 | 
| -    if (len < kBmpHeaderSize + kBmpOS2InfoSize) {
 | 
| -      return false;
 | 
| -    }
 | 
| -    colLen = 3;
 | 
| -    width_ = GetShort();
 | 
| -    height_ = GetShort();
 | 
| -    GetShort();  // Planes.
 | 
| -    bpp_ = GetShort();
 | 
| -  }
 | 
| -  if (height_ < 0) {
 | 
| -    height_ = -height_;
 | 
| -    inverted_ = false;
 | 
| -  }
 | 
| -  if (width_ <= 0 || width_ > kMaxDim || height_ <= 0 || height_ > kMaxDim) {
 | 
| -    return false;
 | 
| -  }
 | 
| -  if (width_ * height_ > max_pixels) {
 | 
| -    return false;
 | 
| -  }
 | 
| -  if (cols < 0 || cols > 256) {
 | 
| -    return false;
 | 
| -  }
 | 
| -  // Allocate then read in the colour map.
 | 
| -  if (cols == 0 && bpp_ <= 8) {
 | 
| -    cols = 1 << bpp_;
 | 
| -  }
 | 
| -  if (bpp_ <= 8 || cols > 0) {
 | 
| -    uint8* colBuf = new uint8[256 * 3];
 | 
| -    memset(colBuf, '\0', 256 * 3);
 | 
| -    colTab_.reset(colBuf);
 | 
| -  }
 | 
| -  if (cols > 0) {
 | 
| -    if (pos_ + (cols * colLen) > len_) {
 | 
| -      return false;
 | 
| -    }
 | 
| -    for (int i = 0; i < cols; ++i) {
 | 
| -      int base = i * 3;
 | 
| -      colTab_[base + 2] = GetByte();
 | 
| -      colTab_[base + 1] = GetByte();
 | 
| -      colTab_[base] = GetByte();
 | 
| -      if (colLen == 4) {
 | 
| -        GetByte();
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -  // Read in the compression data if necessary.
 | 
| -  redBits_ = 0x7c00;
 | 
| -  greenBits_ = 0x03e0;
 | 
| -  blueBits_ = 0x001f;
 | 
| -  bool rle = false;
 | 
| -  if (comp == 1 || comp == 2) {
 | 
| -    rle = true;
 | 
| -  } else if (comp == 3) {
 | 
| -    if (pos_ + 12 > len_) {
 | 
| -      return false;
 | 
| -    }
 | 
| -    redBits_ = GetInt() & 0xffff;
 | 
| -    greenBits_ = GetInt() & 0xffff;
 | 
| -    blueBits_ = GetInt() & 0xffff;
 | 
| -  }
 | 
| -  redShiftRight_ = CalcShiftRight(redBits_);
 | 
| -  greenShiftRight_ = CalcShiftRight(greenBits_);
 | 
| -  blueShiftRight_ = CalcShiftRight(blueBits_);
 | 
| -  redShiftLeft_ = CalcShiftLeft(redBits_);
 | 
| -  greenShiftLeft_ = CalcShiftLeft(greenBits_);
 | 
| -  blueShiftLeft_ = CalcShiftLeft(blueBits_);
 | 
| -  rowPad_ = 0;
 | 
| -  pixelPad_ = 0;
 | 
| -  int rowLen;
 | 
| -  if (bpp_ == 32) {
 | 
| -    rowLen = width_ * 4;
 | 
| -    pixelPad_ = 1;
 | 
| -  } else if (bpp_ == 24) {
 | 
| -    rowLen = width_ * 3;
 | 
| -  } else if (bpp_ == 16) {
 | 
| -    rowLen = width_ * 2;
 | 
| -  } else if (bpp_ == 8) {
 | 
| -    rowLen = width_;
 | 
| -  } else if (bpp_ == 4) {
 | 
| -    rowLen = width_ / 2;
 | 
| -    if (width_ & 1) {
 | 
| -      rowLen++;
 | 
| -    }
 | 
| -  } else if (bpp_ == 1) {
 | 
| -    rowLen = width_ / 8;
 | 
| -    if (width_ & 7) {
 | 
| -      rowLen++;
 | 
| -    }
 | 
| -  } else {
 | 
| -    return false;
 | 
| -  }
 | 
| -  // Round the rowLen up to a multiple of 4.
 | 
| -  if (rowLen % 4 != 0) {
 | 
| -    rowPad_ = 4 - (rowLen % 4);
 | 
| -    rowLen += rowPad_;
 | 
| -  }
 | 
| -
 | 
| -  if (offset > 0 && (size_t)offset > pos_ && (size_t)offset < len_) {
 | 
| -    pos_ = offset;
 | 
| -  }
 | 
| -  // Deliberately off-by-one; a load of BMPs seem to have their last byte
 | 
| -  // missing.
 | 
| -  if (!rle && (pos_ + (rowLen * height_) > len_ + 1)) {
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  output_ = callback->SetSize(width_, height_);
 | 
| -  if (nullptr == output_) {
 | 
| -    return true;  // meaning we succeeded, but they want us to stop now
 | 
| -  }
 | 
| -
 | 
| -  if (rle && (bpp_ == 4 || bpp_ == 8)) {
 | 
| -    DoRLEDecode();
 | 
| -  } else {
 | 
| -    DoStandardDecode();
 | 
| -  }
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -void BmpDecoderHelper::DoRLEDecode() {
 | 
| -  static const uint8 RLE_ESCAPE = 0;
 | 
| -  static const uint8 RLE_EOL = 0;
 | 
| -  static const uint8 RLE_EOF = 1;
 | 
| -  static const uint8 RLE_DELTA = 2;
 | 
| -  int x = 0;
 | 
| -  int y = height_ - 1;
 | 
| -  while (pos_ + 1 < len_) {
 | 
| -    uint8 cmd = GetByte();
 | 
| -    if (cmd != RLE_ESCAPE) {
 | 
| -      uint8 pixels = GetByte();
 | 
| -      int num = 0;
 | 
| -      uint8 col = pixels;
 | 
| -      while (cmd-- && x < width_) {
 | 
| -        if (bpp_ == 4) {
 | 
| -          if (num & 1) {
 | 
| -            col = pixels & 0xf;
 | 
| -          } else {
 | 
| -            col = pixels >> 4;
 | 
| -          }
 | 
| -        }
 | 
| -        PutPixel(x++, y, col);
 | 
| -        num++;
 | 
| -      }
 | 
| -    } else {
 | 
| -      cmd = GetByte();
 | 
| -      if (cmd == RLE_EOF) {
 | 
| -        return;
 | 
| -      } else if (cmd == RLE_EOL) {
 | 
| -        x = 0;
 | 
| -        y--;
 | 
| -        if (y < 0) {
 | 
| -          return;
 | 
| -        }
 | 
| -      } else if (cmd == RLE_DELTA) {
 | 
| -        if (pos_ + 1 < len_) {
 | 
| -          uint8 dx = GetByte();
 | 
| -          uint8 dy = GetByte();
 | 
| -          x += dx;
 | 
| -          if (x > width_) {
 | 
| -            x = width_;
 | 
| -          }
 | 
| -          y -= dy;
 | 
| -          if (y < 0) {
 | 
| -            return;
 | 
| -          }
 | 
| -        }
 | 
| -      } else {
 | 
| -        int num = 0;
 | 
| -        int bytesRead = 0;
 | 
| -        uint8 val = 0;
 | 
| -        while (cmd-- && pos_ < len_) {
 | 
| -          if (bpp_ == 8 || !(num & 1)) {
 | 
| -            val = GetByte();
 | 
| -            bytesRead++;
 | 
| -          }
 | 
| -          uint8 col = val;
 | 
| -          if (bpp_ == 4) {
 | 
| -            if (num & 1) {
 | 
| -              col = col & 0xf;
 | 
| -            } else {
 | 
| -              col >>= 4;
 | 
| -            }
 | 
| -          }
 | 
| -          if (x < width_) {
 | 
| -            PutPixel(x++, y, col);
 | 
| -          }
 | 
| -          num++;
 | 
| -        }
 | 
| -        // All pixel runs must be an even number of bytes - skip a byte if we
 | 
| -        // read an odd number.
 | 
| -        if ((bytesRead & 1) && pos_ < len_) {
 | 
| -          GetByte();
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void BmpDecoderHelper::PutPixel(int x, int y, uint8 col) {
 | 
| -  CHECK(x >= 0 && x < width_);
 | 
| -  CHECK(y >= 0 && y < height_);
 | 
| -  if (!inverted_) {
 | 
| -    y = height_ - (y + 1);
 | 
| -  }
 | 
| -
 | 
| -  int base = ((y * width_) + x) * 3;
 | 
| -  int colBase = col * 3;
 | 
| -  output_[base] = colTab_[colBase];
 | 
| -  output_[base + 1] = colTab_[colBase + 1];
 | 
| -  output_[base + 2] = colTab_[colBase + 2];
 | 
| -}
 | 
| -
 | 
| -void BmpDecoderHelper::DoStandardDecode() {
 | 
| -  int row = 0;
 | 
| -  uint8 currVal = 0;
 | 
| -  for (int h = height_ - 1; h >= 0; h--, row++) {
 | 
| -    int realH = h;
 | 
| -    if (!inverted_) {
 | 
| -      realH = height_ - (h + 1);
 | 
| -    }
 | 
| -    uint8* line = output_ + (3 * width_ * realH);
 | 
| -    for (int w = 0; w < width_; w++) {
 | 
| -      if (bpp_ >= 24) {
 | 
| -        line[2] = GetByte();
 | 
| -        line[1] = GetByte();
 | 
| -        line[0] = GetByte();
 | 
| -      } else if (bpp_ == 16) {
 | 
| -        uint32 val = GetShort();
 | 
| -        line[0] = ((val & redBits_) >> redShiftRight_) << redShiftLeft_;
 | 
| -        line[1] = ((val & greenBits_) >> greenShiftRight_) << greenShiftLeft_;
 | 
| -        line[2] = ((val & blueBits_) >> blueShiftRight_) << blueShiftLeft_;
 | 
| -      } else if (bpp_ <= 8) {
 | 
| -        uint8 col;
 | 
| -        if (bpp_ == 8) {
 | 
| -          col = GetByte();
 | 
| -        } else if (bpp_ == 4) {
 | 
| -          if ((w % 2) == 0) {
 | 
| -            currVal = GetByte();
 | 
| -            col = currVal >> 4;
 | 
| -          } else {
 | 
| -            col = currVal & 0xf;
 | 
| -          }
 | 
| -        } else {
 | 
| -          if ((w % 8) == 0) {
 | 
| -            currVal = GetByte();
 | 
| -          }
 | 
| -          int bit = w & 7;
 | 
| -          col = ((currVal >> (7 - bit)) & 1);
 | 
| -        }
 | 
| -        int base = col * 3;
 | 
| -        line[0] = colTab_[base];
 | 
| -        line[1] = colTab_[base + 1];
 | 
| -        line[2] = colTab_[base + 2];
 | 
| -      }
 | 
| -      line += 3;
 | 
| -      for (int i = 0; i < pixelPad_; ++i) {
 | 
| -        GetByte();
 | 
| -      }
 | 
| -    }
 | 
| -    for (int i = 0; i < rowPad_; ++i) {
 | 
| -      GetByte();
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -int BmpDecoderHelper::GetInt() {
 | 
| -  uint8 b1 = GetByte();
 | 
| -  uint8 b2 = GetByte();
 | 
| -  uint8 b3 = GetByte();
 | 
| -  uint8 b4 = GetByte();
 | 
| -  return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
 | 
| -}
 | 
| -
 | 
| -int BmpDecoderHelper::GetShort() {
 | 
| -  uint8 b1 = GetByte();
 | 
| -  uint8 b2 = GetByte();
 | 
| -  return b1 | (b2 << 8);
 | 
| -}
 | 
| -
 | 
| -uint8 BmpDecoderHelper::GetByte() {
 | 
| -  CHECK(pos_ <= len_);
 | 
| -  // We deliberately allow this off-by-one access to cater for BMPs with their
 | 
| -  // last byte missing.
 | 
| -  if (pos_ == len_) {
 | 
| -    return 0;
 | 
| -  }
 | 
| -  return data_[pos_++];
 | 
| -}
 | 
| -
 | 
| -int BmpDecoderHelper::CalcShiftRight(uint32 mask) {
 | 
| -  int ret = 0;
 | 
| -  while (mask != 0 && !(mask & 1)) {
 | 
| -    mask >>= 1;
 | 
| -    ret++;
 | 
| -  }
 | 
| -  return ret;
 | 
| -}
 | 
| -
 | 
| -int BmpDecoderHelper::CalcShiftLeft(uint32 mask) {
 | 
| -  int ret = 0;
 | 
| -  while (mask != 0 && !(mask & 1)) {
 | 
| -    mask >>= 1;
 | 
| -  }
 | 
| -  while (mask != 0 && !(mask & 0x80)) {
 | 
| -    mask <<= 1;
 | 
| -    ret++;
 | 
| -  }
 | 
| -  return ret;
 | 
| -}
 | 
| -
 | 
| -}  // namespace image_codec
 | 
| 
 |