C++ Port:
authorralf.kistner@gmail.com <ralf.kistner@gmail.com@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 5 Nov 2009 22:11:15 +0000 (22:11 +0000)
committerralf.kistner@gmail.com <ralf.kistner@gmail.com@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 5 Nov 2009 22:11:15 +0000 (22:11 +0000)
- Fixed to be able to build for the Symbian emulator (variable-sized arrays cannot be created on the stack).
- Fixed bug only present on Symbian phones that prevented the alignment patterns from being found (the Symbian implementation of valarray does not initialize its values to 0, unless it is explicitly specified as the default value).
- Fixed an include.

git-svn-id: http://zxing.googlecode.com/svn/trunk@1100 59b500cc-1b3d-0410-9834-0bbf25fbcc57

cpp/SConscript
cpp/core/src/zxing/common/Array.h
cpp/core/src/zxing/qrcode/decoder/DecodedBitStreamParser.cpp
cpp/core/src/zxing/qrcode/detector/AlignmentPatternFinder.cpp

index 22bb17e..d324545 100644 (file)
@@ -1,42 +1,42 @@
-Decider('MD5')
-
-env = Environment()
-
-debug = True
-compile_options = {}
-flags = []
-if debug:
-       #compile_options['CPPDEFINES'] = "-DDEBUG"
-       flags.append("-O0 -g3 -Wall")
-compile_options['CXXFLAGS'] = ' '.join(flags)
-
-
-def all_files(dir, ext='.cpp', level=5):
-       files = []
-       for i in range(level):
-               files += Glob(dir + ('/*' * i) + ext) 
-       return files
-
-
-
-magick_include = ['/usr/include/ImageMagick/']
-magick_libs = ['Magick++', 'MagickWand', 'MagickCore']
-
-cppunit_libs = ['cppunit']
-
-zxing_files = all_files('core/src')
-
-zxing_include = ['core/src']
-zxing_libs = env.Library('zxing', source=zxing_files, CPPPATH=zxing_include, **compile_options)
-
-app_files = all_files('magick/src')
-app_executable = env.Program('zxing', app_files, CPPPATH=magick_include + zxing_include, LIBS=magick_libs + zxing_libs, **compile_options)
-
-test_files = all_files('core/tests/src')
-test_executable = env.Program('testrunner', test_files, CPPPATH=zxing_include, LIBS=zxing_libs + cppunit_libs, **compile_options)
-
-
-Alias('lib', zxing_libs)
-Alias('tests', test_executable)
-Alias('zxing', app_executable)
-
+Decider('MD5')\r
+\r
+env = Environment()\r
+\r
+debug = True\r
+compile_options = {}\r
+flags = []\r
+if debug:\r
+       #compile_options['CPPDEFINES'] = "-DDEBUG"\r
+       flags.append("-O0 -g3 -Wall")\r
+compile_options['CXXFLAGS'] = ' '.join(flags)\r
+\r
+\r
+def all_files(dir, ext='.cpp', level=5):\r
+       files = []\r
+       for i in range(1, level):\r
+               files += Glob(dir + ('/*' * i) + ext) \r
+       return files\r
+\r
+\r
+\r
+magick_include = ['/usr/include/ImageMagick/']\r
+magick_libs = ['Magick++', 'MagickWand', 'MagickCore']\r
+\r
+cppunit_libs = ['cppunit']\r
+\r
+zxing_files = all_files('core/src')\r
+\r
+zxing_include = ['core/src']\r
+zxing_libs = env.Library('zxing', source=zxing_files, CPPPATH=zxing_include, **compile_options)\r
+\r
+app_files = all_files('magick/src')\r
+app_executable = env.Program('zxing', app_files, CPPPATH=magick_include + zxing_include, LIBS=magick_libs + zxing_libs, **compile_options)\r
+\r
+test_files = all_files('core/tests/src')\r
+test_executable = env.Program('testrunner', test_files, CPPPATH=zxing_include, LIBS=zxing_libs + cppunit_libs, **compile_options)\r
+\r
+\r
+Alias('lib', zxing_libs)\r
+Alias('tests', test_executable)\r
+Alias('zxing', app_executable)\r
+\r
index 150819d..39b1786 100644 (file)
-#ifndef __ARRAY_H__
-#define __ARRAY_H__
-
-/*
- *  Array.h
- *  zxing
- *
- *  Created by Christian Brunschen on 07/05/2008.
- *  Copyright 2008 Google UK. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <valarray>
-#include <cstdarg>
-
-#ifdef DEBUG_COUNTING
-#include <iostream>
-#include <typeinfo>
-#endif
-
-#include "Counted.h"
-
-
-namespace zxing {
-
-template<typename T> class Array : public Counted {
-protected:
-public:
-  std::valarray<T> values_;
-  Array(size_t n) :
-      Counted(), values_(T(), n) {
-  }
-  Array(T *ts, size_t n) :
-      Counted(), values_(ts, n) {
-  }
-  Array(T v, size_t n) :
-      Counted(), values_(v, n) {
-  }
-  Array(std::valarray<T> &v) :
-      Counted(), values_(v) {
-  }
-  Array(Array<T> &other) :
-      Counted(), values_(other.values_) {
-  }
-  Array(Array<T> *other) :
-      Counted(), values_(other->values_) {
-  }
-  virtual ~Array() {
-  }
-  Array<T>& operator=(const Array<T> &other) {
-#ifdef DEBUG_COUNTING
-    cout << "assigning values from Array " << &other << " to this Array " << this << ", ";
-#endif
-    values_ = other.values_;
-#ifdef DEBUG_COUNTING
-    cout << "new size = " << values_.size() << "\n";
-#endif
-    return *this;
-  }
-  Array<T>& operator=(const std::valarray<T> &array) {
-#ifdef DEBUG_COUNTING
-    cout << "assigning values from Array " << &array << " to this Array " << this << ", ";
-#endif
-    values_ = array;
-#ifdef DEBUG_COUNTING
-    cout << "new size = " << values_.size() << "\n";
-#endif
-    return *this;
-  }
-  T operator[](size_t i) const {
-    return values_[i];
-  }
-  T& operator[](size_t i) {
-    return values_[i];
-  }
-  size_t size() const {
-    return values_.size();
-  }
-  std::valarray<T> values() const {
-    return values_;
-  }
-  std::valarray<T>& values() {
-    return values_;
-  }
-};
-
-template<typename T> class ArrayRef {
-private:
-public:
-  Array<T> *array_;
-  ArrayRef() :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating empty ArrayRef " << this << "\n";
-#endif
-  }
-  ArrayRef(size_t n) :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating ArrayRef " << this << "with size " << n << "\n";
-#endif
-    reset(new Array<T> (n));
-  }
-  ArrayRef(T *ts, size_t n) :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating ArrayRef " << this << "with " << n << " elements at " << (void *)ts << "\n";
-#endif
-    reset(new Array<T> (ts, n));
-  }
-  ArrayRef(Array<T> *a) :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating ArrayRef " << this << " from pointer:\n";
-#endif
-    reset(a);
-  }
-  ArrayRef(const Array<T> &a) :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating ArrayRef " << this << " from reference to Array " << (void *)&a << ":\n";
-#endif
-    reset(const_cast<Array<T> *>(&a));
-  }
-  ArrayRef(const ArrayRef &other) :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";
-#endif
-    reset(other.array_);
-  }
-
-  template<class Y>
-  ArrayRef(const ArrayRef<Y> &other) :
-      array_(0) {
-#ifdef DEBUG_COUNTING
-    cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";
-#endif
-    reset(static_cast<const Array<T> *>(other.array_));
-  }
-
-  ~ArrayRef() {
-#ifdef DEBUG_COUNTING
-    cout << "destroying ArrayRef " << this << " with " << (array_ ? typeid(*array_).name() : "NULL") << " "
-         << array_ << "\n";
-#endif
-    if (array_) {
-      array_->release();
-    }
-    array_ = 0;
-  }
-
-  T operator[](size_t i) const {
-    return (*array_)[i];
-  }
-  T& operator[](size_t i) {
-    return (*array_)[i];
-  }
-  size_t size() const {
-    return array_->size();
-  }
-
-  void reset(Array<T> *a) {
-#ifdef DEBUG_COUNTING
-    cout << "resetting ArrayRef " << this << " from " << (array_ ? typeid(*array_).name() : "NULL") << " "
-         << array_ << " to " << (a ? typeid(*a).name() : "NULL") << " " << a << "\n";
-#endif
-    if (a) {
-      a->retain();
-    }
-    if (array_) {
-      array_->release();
-    }
-    array_ = a;
-  }
-  void reset(const ArrayRef<T> &other) {
-    reset(other.array_);
-  }
-  ArrayRef<T>& operator=(const ArrayRef<T> &other) {
-    reset(other);
-    return *this;
-  }
-  ArrayRef<T>& operator=(Array<T> *a) {
-    reset(a);
-    return *this;
-  }
-
-  Array<T>& operator*() {
-    return *array_;
-  }
-  Array<T>* operator->() {
-    return array_;
-  }
-};
-
-} // namespace zxing
-
-#endif // __ARRAY_H__
+#ifndef __ARRAY_H__\r
+#define __ARRAY_H__\r
+\r
+/*\r
+ *  Array.h\r
+ *  zxing\r
+ *\r
+ *  Created by Christian Brunschen on 07/05/2008.\r
+ *  Copyright 2008 Google UK. All rights reserved.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <valarray>\r
+#include <cstdarg>\r
+\r
+#ifdef DEBUG_COUNTING\r
+#include <iostream>\r
+#include <typeinfo>\r
+#endif\r
+\r
+#include <zxing/common/Counted.h>\r
+\r
+\r
+namespace zxing {\r
+\r
+template<typename T> class Array : public Counted {\r
+protected:\r
+public:\r
+  std::valarray<T> values_;\r
+  Array(size_t n) :\r
+      Counted(), values_(T(), n) {\r
+  }\r
+  Array(T *ts, size_t n) :\r
+      Counted(), values_(ts, n) {\r
+  }\r
+  Array(T v, size_t n) :\r
+      Counted(), values_(v, n) {\r
+  }\r
+  Array(std::valarray<T> &v) :\r
+      Counted(), values_(v) {\r
+  }\r
+  Array(Array<T> &other) :\r
+      Counted(), values_(other.values_) {\r
+  }\r
+  Array(Array<T> *other) :\r
+      Counted(), values_(other->values_) {\r
+  }\r
+  virtual ~Array() {\r
+  }\r
+  Array<T>& operator=(const Array<T> &other) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "assigning values from Array " << &other << " to this Array " << this << ", ";\r
+#endif\r
+    values_ = other.values_;\r
+#ifdef DEBUG_COUNTING\r
+    cout << "new size = " << values_.size() << "\n";\r
+#endif\r
+    return *this;\r
+  }\r
+  Array<T>& operator=(const std::valarray<T> &array) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "assigning values from Array " << &array << " to this Array " << this << ", ";\r
+#endif\r
+    values_ = array;\r
+#ifdef DEBUG_COUNTING\r
+    cout << "new size = " << values_.size() << "\n";\r
+#endif\r
+    return *this;\r
+  }\r
+  T operator[](size_t i) const {\r
+    return values_[i];\r
+  }\r
+  T& operator[](size_t i) {\r
+    return values_[i];\r
+  }\r
+  size_t size() const {\r
+    return values_.size();\r
+  }\r
+  std::valarray<T> values() const {\r
+    return values_;\r
+  }\r
+  std::valarray<T>& values() {\r
+    return values_;\r
+  }\r
+};\r
+\r
+template<typename T> class ArrayRef {\r
+private:\r
+public:\r
+  Array<T> *array_;\r
+  ArrayRef() :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating empty ArrayRef " << this << "\n";\r
+#endif\r
+  }\r
+  ArrayRef(size_t n) :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating ArrayRef " << this << "with size " << n << "\n";\r
+#endif\r
+    reset(new Array<T> (n));\r
+  }\r
+  ArrayRef(T *ts, size_t n) :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating ArrayRef " << this << "with " << n << " elements at " << (void *)ts << "\n";\r
+#endif\r
+    reset(new Array<T> (ts, n));\r
+  }\r
+  ArrayRef(Array<T> *a) :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating ArrayRef " << this << " from pointer:\n";\r
+#endif\r
+    reset(a);\r
+  }\r
+  ArrayRef(const Array<T> &a) :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating ArrayRef " << this << " from reference to Array " << (void *)&a << ":\n";\r
+#endif\r
+    reset(const_cast<Array<T> *>(&a));\r
+  }\r
+  ArrayRef(const ArrayRef &other) :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";\r
+#endif\r
+    reset(other.array_);\r
+  }\r
+\r
+  template<class Y>\r
+  ArrayRef(const ArrayRef<Y> &other) :\r
+      array_(0) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";\r
+#endif\r
+    reset(static_cast<const Array<T> *>(other.array_));\r
+  }\r
+\r
+  ~ArrayRef() {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "destroying ArrayRef " << this << " with " << (array_ ? typeid(*array_).name() : "NULL") << " "\r
+         << array_ << "\n";\r
+#endif\r
+    if (array_) {\r
+      array_->release();\r
+    }\r
+    array_ = 0;\r
+  }\r
+\r
+  T operator[](size_t i) const {\r
+    return (*array_)[i];\r
+  }\r
+  T& operator[](size_t i) {\r
+    return (*array_)[i];\r
+  }\r
+  size_t size() const {\r
+    return array_->size();\r
+  }\r
+\r
+  void reset(Array<T> *a) {\r
+#ifdef DEBUG_COUNTING\r
+    cout << "resetting ArrayRef " << this << " from " << (array_ ? typeid(*array_).name() : "NULL") << " "\r
+         << array_ << " to " << (a ? typeid(*a).name() : "NULL") << " " << a << "\n";\r
+#endif\r
+    if (a) {\r
+      a->retain();\r
+    }\r
+    if (array_) {\r
+      array_->release();\r
+    }\r
+    array_ = a;\r
+  }\r
+  void reset(const ArrayRef<T> &other) {\r
+    reset(other.array_);\r
+  }\r
+  ArrayRef<T>& operator=(const ArrayRef<T> &other) {\r
+    reset(other);\r
+    return *this;\r
+  }\r
+  ArrayRef<T>& operator=(Array<T> *a) {\r
+    reset(a);\r
+    return *this;\r
+  }\r
+\r
+  Array<T>& operator*() {\r
+    return *array_;\r
+  }\r
+  Array<T>* operator->() {\r
+    return array_;\r
+  }\r
+};\r
+\r
+} // namespace zxing\r
+\r
+#endif // __ARRAY_H__\r
index d21d2e9..e4766ed 100644 (file)
 #include <iconv.h>
 
 // Required for compatibility. TODO: test on Symbian
+#ifdef ZXING_ICONV_CONST
+#undef ICONV_CONST
+#define ICONV_CONST const
+#endif
+
 #ifndef ICONV_CONST
 #define ICONV_CONST /**/
 #endif
@@ -51,8 +56,8 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
   }
 
   iconv_t cd = iconv_open(UTF8, src);
-  int maxOut = 4 * nIn + 1;
-  unsigned char bufOut[maxOut];
+  const int maxOut = 4 * nIn + 1;
+  unsigned char* bufOut = new unsigned char[maxOut];
 
   ICONV_CONST char *fromPtr = (ICONV_CONST char *)bufIn;
   size_t nFrom = nIn;
@@ -63,6 +68,7 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
     size_t oneway = iconv(cd, &fromPtr, &nFrom, &toPtr, &nTo);
     if (oneway == (size_t)(-1)) {
       iconv_close(cd);
+      delete[] bufOut;
       throw ReaderException("error converting characters");
     }
   }
@@ -72,13 +78,14 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
   bufOut[nResult] = '\0';
 
   ost << bufOut;
+  delete[] bufOut;
 }
 
 void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, ostringstream &result, int count) {
   // Each character will require 2 bytes. Read the characters as 2-byte pairs
   // and decode as Shift_JIS afterwards
   size_t nBytes = 2 * count;
-  unsigned char buffer[nBytes];
+  unsigned char* buffer = new unsigned char[nBytes];
   int offset = 0;
   while (count > 0) {
     // Each 13 bits encodes a 2-byte character
@@ -99,14 +106,16 @@ void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, ostringstre
   }
 
   append(result, buffer, nBytes, SHIFT_JIS);
+  delete[] buffer;
 }
 
 void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits, ostringstream &result, int count) {
   int nBytes = count;
-  unsigned char readBytes[nBytes];
+  unsigned char* readBytes = new unsigned char[nBytes];
   if (count << 3 > bits->available()) {
     ostringstream s;
     s << "Count too large: " << count;
+    delete[] readBytes;
     throw ReaderException(s.str().c_str());
   }
   for (int i = 0; i < count; i++) {
@@ -119,11 +128,12 @@ void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits, ostringstrea
   // give a hint.
   const char *encoding = guessEncoding(readBytes, nBytes);
   append(result, readBytes, nBytes, encoding);
+  delete[] readBytes;
 }
 
 void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringstream &result, int count) {
   int nBytes = count;
-  unsigned char bytes[nBytes];
+  unsigned char* bytes = new unsigned char[nBytes];
   int i = 0;
   // Read three digits at a time
   while (count >= 3) {
@@ -132,6 +142,7 @@ void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringst
     if (threeDigitsBits >= 1000) {
       ostringstream s;
       s << "Illegal value for 3-digit unit: " << threeDigitsBits;
+      delete[] bytes;
       throw ReaderException(s.str().c_str());
     }
     bytes[i++] = ALPHANUMERIC_CHARS[threeDigitsBits / 100];
@@ -145,6 +156,7 @@ void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringst
     if (twoDigitsBits >= 100) {
       ostringstream s;
       s << "Illegal value for 2-digit unit: " << twoDigitsBits;
+      delete[] bytes;
       throw ReaderException(s.str().c_str());
     }
     bytes[i++] = ALPHANUMERIC_CHARS[twoDigitsBits / 10];
@@ -155,16 +167,18 @@ void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringst
     if (digitBits >= 10) {
       ostringstream s;
       s << "Illegal value for digit unit: " << digitBits;
+      delete[] bytes;
       throw ReaderException(s.str().c_str());
     }
     bytes[i++] = ALPHANUMERIC_CHARS[digitBits];
   }
   append(result, bytes, nBytes, ASCII);
+  delete[] bytes;
 }
 
 void DecodedBitStreamParser::decodeAlphanumericSegment(Ref<BitSource> bits, ostringstream &result, int count) {
   int nBytes = count;
-  unsigned char bytes[nBytes];
+  unsigned char* bytes = new unsigned char[nBytes];
   int i = 0;
   // Read two characters at a time
   while (count > 1) {
@@ -177,6 +191,7 @@ void DecodedBitStreamParser::decodeAlphanumericSegment(Ref<BitSource> bits, ostr
     bytes[i++] = ALPHANUMERIC_CHARS[bits->readBits(6)];
   }
   append(result, bytes, nBytes, ASCII);
+  delete[] bytes;
 }
 
 const char *
index 87af79e..029f5b8 100644 (file)
@@ -46,7 +46,7 @@ bool AlignmentPatternFinder::foundPatternCross(valarray<int> &stateCount) {
 float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount,
     int originalStateCountTotal) {
   int maxI = image_->getHeight();
-  valarray<int> stateCount(3);
+  valarray<int> stateCount(0, 3);
 
 
   // Start counting up from center
@@ -136,7 +136,7 @@ Ref<AlignmentPattern> AlignmentPatternFinder::find() {
   //      Ref<BitArray> luminanceRow(new BitArray(width_));
   // We are looking for black/white/black modules in 1:1:1 ratio;
   // this tracks the number of black/white/black modules seen so far
-  valarray<int> stateCount(3);
+  valarray<int> stateCount(0, 3);
   for (size_t iGen = 0; iGen < height_; iGen++) {
     // Search from middle outwards
     size_t i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));