Browse Source

qrcode scan works

tags/2.3
clowwindy 9 years ago
parent
commit
f6939f1119
17 changed files with 3060 additions and 22 deletions
  1. +152
    -0
      shadowsocks-csharp/3rd/zxing/BarcodeReader.cs
  2. +436
    -0
      shadowsocks-csharp/3rd/zxing/BarcodeReaderGeneric.cs
  3. +161
    -0
      shadowsocks-csharp/3rd/zxing/IBarcodeReader.cs
  4. +123
    -0
      shadowsocks-csharp/3rd/zxing/IBarcodeReaderGeneric.cs
  5. +314
    -0
      shadowsocks-csharp/3rd/zxing/RGBLuminanceSource.cs
  6. +128
    -0
      shadowsocks-csharp/3rd/zxing/common/CharacterSetECI.cs
  7. +370
    -0
      shadowsocks-csharp/3rd/zxing/common/DecodingOptions.cs
  8. +66
    -0
      shadowsocks-csharp/3rd/zxing/common/ECI.cs
  9. +243
    -0
      shadowsocks-csharp/3rd/zxing/common/GlobalHistogramBinarizer.cs
  10. +288
    -0
      shadowsocks-csharp/3rd/zxing/common/HybridBinarizer.cs
  11. +266
    -0
      shadowsocks-csharp/3rd/zxing/common/StringUtils.cs
  12. +102
    -0
      shadowsocks-csharp/3rd/zxing/net2.0/Action.cs
  13. +122
    -0
      shadowsocks-csharp/3rd/zxing/net2.0/Func.cs
  14. +29
    -0
      shadowsocks-csharp/3rd/zxing/net2.0/TimeZoneInfo.cs
  15. +234
    -3
      shadowsocks-csharp/3rd/zxing/qrcode/decoder/DecodedBitStreamParser.cs
  16. +12
    -19
      shadowsocks-csharp/View/MenuViewController.cs
  17. +14
    -0
      shadowsocks-csharp/shadowsocks-csharp.csproj

+ 152
- 0
shadowsocks-csharp/3rd/zxing/BarcodeReader.cs View File

@@ -0,0 +1,152 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
using System;
#if !PORTABLE
#if !(SILVERLIGHT || NETFX_CORE)
#if !UNITY
using System.Drawing;
using ZXing.QrCode;
#else
using UnityEngine;
#endif
#elif NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#else
using System.Windows.Media.Imaging;
#endif
#endif
#if MONOANDROID
using Android.Graphics;
#endif
namespace ZXing
{
/// <summary>
/// A smart class to decode the barcode inside a bitmap object
/// </summary>
#if MONOTOUCH
public class BarcodeReader : BarcodeReaderGeneric<MonoTouch.UIKit.UIImage>, IBarcodeReader, IMultipleBarcodeReader
{
private static readonly Func<MonoTouch.UIKit.UIImage, LuminanceSource> defaultCreateLuminanceSource =
(img) => new RGBLuminanceSource(img);
#else
#if !PORTABLE
#if !(SILVERLIGHT || NETFX_CORE)
#if !UNITY
public class BarcodeReader : BarcodeReaderGeneric<Bitmap>, IBarcodeReader
{
private static readonly Func<Bitmap, LuminanceSource> defaultCreateLuminanceSource =
(bitmap) => new BitmapLuminanceSource(bitmap);
#else
public class BarcodeReader : BarcodeReaderGeneric<Color32[]>, IBarcodeReader, IMultipleBarcodeReader
{
private static readonly Func<Color32[], int, int, LuminanceSource> defaultCreateLuminanceSource =
(rawColor32, width, height) => new Color32LuminanceSource(rawColor32, width, height);
#endif
#else
public class BarcodeReader : BarcodeReaderGeneric<WriteableBitmap>, IBarcodeReader, IMultipleBarcodeReader
{
private static readonly Func<WriteableBitmap, LuminanceSource> defaultCreateLuminanceSource =
(bitmap) => new BitmapLuminanceSource(bitmap);
#endif
#else
public class BarcodeReader : BarcodeReaderGeneric<byte[]>, IBarcodeReader, IMultipleBarcodeReader
{
private static readonly Func<byte[], LuminanceSource> defaultCreateLuminanceSource =
(data) => null;
#endif
#endif
/// <summary>
/// Initializes a new instance of the <see cref="BarcodeReader"/> class.
/// </summary>
public BarcodeReader()
: this(new QRCodeReader(), defaultCreateLuminanceSource, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BarcodeReader"/> class.
/// </summary>
/// <param name="reader">Sets the reader which should be used to find and decode the barcode.
/// If null then MultiFormatReader is used</param>
/// <param name="createLuminanceSource">Sets the function to create a luminance source object for a bitmap.
/// If null, an exception is thrown when Decode is called</param>
/// <param name="createBinarizer">Sets the function to create a binarizer object for a luminance source.
/// If null then HybridBinarizer is used</param>
public BarcodeReader(Reader reader,
#if MONOTOUCH
Func<MonoTouch.UIKit.UIImage, LuminanceSource> createLuminanceSource,
#elif MONOANDROID
Func<Android.Graphics.Bitmap, LuminanceSource> createLuminanceSource,
#else
#if !(SILVERLIGHT || NETFX_CORE)
#if !UNITY
#if !PORTABLE
Func<Bitmap, LuminanceSource> createLuminanceSource,
#else
Func<byte[], LuminanceSource> createLuminanceSource,
#endif
#else
Func<Color32[], int, int, LuminanceSource> createLuminanceSource,
#endif
#else
Func<WriteableBitmap, LuminanceSource> createLuminanceSource,
#endif
#endif
Func<LuminanceSource, Binarizer> createBinarizer
)
: base(reader, createLuminanceSource ?? defaultCreateLuminanceSource, createBinarizer)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BarcodeReader"/> class.
/// </summary>
/// <param name="reader">Sets the reader which should be used to find and decode the barcode.
/// If null then MultiFormatReader is used</param>
/// <param name="createLuminanceSource">Sets the function to create a luminance source object for a bitmap.
/// If null, an exception is thrown when Decode is called</param>
/// <param name="createBinarizer">Sets the function to create a binarizer object for a luminance source.
/// If null then HybridBinarizer is used</param>
public BarcodeReader(Reader reader,
#if MONOTOUCH
Func<MonoTouch.UIKit.UIImage, LuminanceSource> createLuminanceSource,
#elif MONOANDROID
Func<Android.Graphics.Bitmap, LuminanceSource> createLuminanceSource,
#else
#if !(SILVERLIGHT || NETFX_CORE)
#if !UNITY
#if !PORTABLE
Func<Bitmap, LuminanceSource> createLuminanceSource,
#else
Func<byte[], LuminanceSource> createLuminanceSource,
#endif
#else
Func<Color32[], int, int, LuminanceSource> createLuminanceSource,
#endif
#else
Func<WriteableBitmap, LuminanceSource> createLuminanceSource,
#endif
#endif
Func<LuminanceSource, Binarizer> createBinarizer,
Func<byte[], int, int, RGBLuminanceSource.BitmapFormat, LuminanceSource> createRGBLuminanceSource
)
: base(reader, createLuminanceSource ?? defaultCreateLuminanceSource, createBinarizer, createRGBLuminanceSource)
{
}
}
}

+ 436
- 0
shadowsocks-csharp/3rd/zxing/BarcodeReaderGeneric.cs View File

@@ -0,0 +1,436 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
using System;
using System.Collections.Generic;
using ZXing.Common;
using ZXing.QrCode;
namespace ZXing
{
/// <summary>
/// A smart class to decode the barcode inside a bitmap object
/// </summary>
public class BarcodeReaderGeneric<T> : IBarcodeReaderGeneric<T>
{
private static readonly Func<LuminanceSource, Binarizer> defaultCreateBinarizer =
(luminanceSource) => new HybridBinarizer(luminanceSource);
protected static readonly Func<byte[], int, int, RGBLuminanceSource.BitmapFormat, LuminanceSource> defaultCreateRGBLuminanceSource =
(rawBytes, width, height, format) => new RGBLuminanceSource(rawBytes, width, height, format);
private Reader reader;
private readonly Func<byte[], int, int, RGBLuminanceSource.BitmapFormat, LuminanceSource> createRGBLuminanceSource;
#if !UNITY
private readonly Func<T, LuminanceSource> createLuminanceSource;
#else
private readonly Func<T, int, int, LuminanceSource> createLuminanceSource;
#endif
private readonly Func<LuminanceSource, Binarizer> createBinarizer;
private bool usePreviousState;
private DecodingOptions options;
/// <summary>
/// Gets or sets the options.
/// </summary>
/// <value>
/// The options.
/// </value>
public DecodingOptions Options
{
get { return options ?? (options = new DecodingOptions()); }
set { options = value; }
}
/// <summary>
/// Gets the reader which should be used to find and decode the barcode.
/// </summary>
/// <value>
/// The reader.
/// </value>
protected Reader Reader
{
get
{
return reader ?? (reader = new QRCodeReader());
}
}
/// <summary>
/// Gets or sets a method which is called if an important point is found
/// </summary>
/// <value>
/// The result point callback.
/// </value>
public event Action<ResultPoint> ResultPointFound
{
add
{
if (!Options.Hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
{
var callback = new ResultPointCallback(OnResultPointFound);
Options.Hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK] = callback;
}
explicitResultPointFound += value;
usePreviousState = false;
}
remove
{
explicitResultPointFound -= value;
if (explicitResultPointFound == null)
Options.Hints.Remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
usePreviousState = false;
}
}
private event Action<ResultPoint> explicitResultPointFound;
/// <summary>
/// event is executed if a result was found via decode
/// </summary>
public event Action<Result> ResultFound;
/// <summary>
/// Gets or sets a flag which cause a deeper look into the bitmap
/// </summary>
/// <value>
/// <c>true</c> if [try harder]; otherwise, <c>false</c>.
/// </value>
[Obsolete("Please use the Options.TryHarder property instead.")]
public bool TryHarder
{
get { return Options.TryHarder; }
set { Options.TryHarder = value; }
}
/// <summary>
/// Image is a pure monochrome image of a barcode.
/// </summary>
/// <value>
/// <c>true</c> if monochrome image of a barcode; otherwise, <c>false</c>.
/// </value>
[Obsolete("Please use the Options.PureBarcode property instead.")]
public bool PureBarcode
{
get { return Options.PureBarcode; }
set { Options.PureBarcode = value; }
}
/// <summary>
/// Specifies what character encoding to use when decoding, where applicable (type String)
/// </summary>
/// <value>
/// The character set.
/// </value>
[Obsolete("Please use the Options.CharacterSet property instead.")]
public string CharacterSet
{
get { return Options.CharacterSet; }
set { Options.CharacterSet = value; }
}
/// <summary>
/// Image is known to be of one of a few possible formats.
/// Maps to a {@link java.util.List} of {@link BarcodeFormat}s.
/// </summary>
/// <value>
/// The possible formats.
/// </value>
[Obsolete("Please use the Options.PossibleFormats property instead.")]
public IList<BarcodeFormat> PossibleFormats
{
get { return Options.PossibleFormats; }
set { Options.PossibleFormats = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the image should be automatically rotated.
/// Rotation is supported for 90, 180 and 270 degrees
/// </summary>
/// <value>
/// <c>true</c> if image should be rotated; otherwise, <c>false</c>.
/// </value>
public bool AutoRotate { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the image should be automatically inverted
/// if no result is found in the original image.
/// ATTENTION: Please be carefully because it slows down the decoding process if it is used
/// </summary>
/// <value>
/// <c>true</c> if image should be inverted; otherwise, <c>false</c>.
/// </value>
public bool TryInverted { get; set; }
#if !UNITY
/// <summary>
/// Optional: Gets or sets the function to create a luminance source object for a bitmap.
/// If null a platform specific default LuminanceSource is used
/// </summary>
/// <value>
/// The function to create a luminance source object.
/// </value>
protected Func<T, LuminanceSource> CreateLuminanceSource
#else
/// <summary>
/// Optional: Gets or sets the function to create a luminance source object for a bitmap.
/// If null a platform specific default LuminanceSource is used
/// </summary>
/// <value>
/// The function to create a luminance source object.
/// </value>
protected Func<T, int, int, LuminanceSource> CreateLuminanceSource
#endif
{
get
{
return createLuminanceSource;
}
}
/// <summary>
/// Optional: Gets or sets the function to create a binarizer object for a luminance source.
/// If null then HybridBinarizer is used
/// </summary>
/// <value>
/// The function to create a binarizer object.
/// </value>
protected Func<LuminanceSource, Binarizer> CreateBinarizer
{
get
{
return createBinarizer ?? defaultCreateBinarizer;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="BarcodeReaderGeneric{T}"/> class.
/// </summary>
public BarcodeReaderGeneric()
: this(new QRCodeReader(), null, defaultCreateBinarizer)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BarcodeReaderGeneric{T}"/> class.
/// </summary>
/// <param name="reader">Sets the reader which should be used to find and decode the barcode.
/// If null then MultiFormatReader is used</param>
/// <param name="createLuminanceSource">Sets the function to create a luminance source object for a bitmap.
/// If null, an exception is thrown when Decode is called</param>
/// <param name="createBinarizer">Sets the function to create a binarizer object for a luminance source.
/// If null then HybridBinarizer is used</param>
public BarcodeReaderGeneric(Reader reader,
#if !UNITY
Func<T, LuminanceSource> createLuminanceSource,
#else
Func<T, int, int, LuminanceSource> createLuminanceSource,
#endif
Func<LuminanceSource, Binarizer> createBinarizer
)
: this(reader, createLuminanceSource, createBinarizer, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BarcodeReaderGeneric{T}"/> class.
/// </summary>
/// <param name="reader">Sets the reader which should be used to find and decode the barcode.
/// If null then MultiFormatReader is used</param>
/// <param name="createLuminanceSource">Sets the function to create a luminance source object for a bitmap.
/// If null, an exception is thrown when Decode is called</param>
/// <param name="createBinarizer">Sets the function to create a binarizer object for a luminance source.
/// If null then HybridBinarizer is used</param>
/// <param name="createRGBLuminanceSource">Sets the function to create a luminance source object for a rgb array.
/// If null the RGBLuminanceSource is used. The handler is only called when Decode with a byte[] array is called.</param>
public BarcodeReaderGeneric(Reader reader,
#if !UNITY
Func<T, LuminanceSource> createLuminanceSource,
#else
Func<T, int, int, LuminanceSource> createLuminanceSource,
#endif
Func<LuminanceSource, Binarizer> createBinarizer,
Func<byte[], int, int, RGBLuminanceSource.BitmapFormat, LuminanceSource> createRGBLuminanceSource
)
{
this.reader = reader ?? new QRCodeReader();
this.createLuminanceSource = createLuminanceSource;
this.createBinarizer = createBinarizer ?? defaultCreateBinarizer;
this.createRGBLuminanceSource = createRGBLuminanceSource ?? defaultCreateRGBLuminanceSource;
Options.ValueChanged += (o, args) => usePreviousState = false;
usePreviousState = false;
}
#if !PORTABLE
#if !UNITY
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="barcodeBitmap">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
public Result Decode(T barcodeBitmap)
#else
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="rawRGB">raw bytes of the image in RGB order</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns>
/// the result data or null
/// </returns>
public Result Decode(T rawRGB, int width, int height)
#endif
{
if (CreateLuminanceSource == null)
{
throw new InvalidOperationException("You have to declare a luminance source delegate.");
}
#if !UNITY
if (barcodeBitmap == null)
throw new ArgumentNullException("barcodeBitmap");
#else
if (rawRGB == null)
throw new ArgumentNullException("rawRGB");
#endif
#if !UNITY
var luminanceSource = CreateLuminanceSource(barcodeBitmap);
#else
var luminanceSource = CreateLuminanceSource(rawRGB, width, height);
#endif
return Decode(luminanceSource);
}
#endif
/// <summary>
/// Tries to decode a barcode within an image which is given by a luminance source.
/// That method gives a chance to prepare a luminance source completely before calling
/// the time consuming decoding method. On the other hand there is a chance to create
/// a luminance source which is independent from external resources (like Bitmap objects)
/// and the decoding call can be made in a background thread.
/// </summary>
/// <param name="luminanceSource">The luminance source.</param>
/// <returns></returns>
virtual public Result Decode(LuminanceSource luminanceSource)
{
var result = default(Result);
var binarizer = CreateBinarizer(luminanceSource);
var binaryBitmap = new BinaryBitmap(binarizer);
var multiformatReader = Reader as QRCodeReader;
var rotationCount = 0;
var rotationMaxCount = 1;
if (AutoRotate)
{
Options.Hints[DecodeHintType.TRY_HARDER_WITHOUT_ROTATION] = true;
rotationMaxCount = 4;
}
else
{
if (Options.Hints.ContainsKey(DecodeHintType.TRY_HARDER_WITHOUT_ROTATION))
Options.Hints.Remove(DecodeHintType.TRY_HARDER_WITHOUT_ROTATION);
}
for (; rotationCount < rotationMaxCount; rotationCount++)
{
result = Reader.decode(binaryBitmap, Options.Hints);
usePreviousState = true;
if (result != null ||
!luminanceSource.RotateSupported ||
!AutoRotate)
break;
binaryBitmap = new BinaryBitmap(CreateBinarizer(luminanceSource.rotateCounterClockwise()));
}
if (result != null)
{
if (result.ResultMetadata == null)
{
result.putMetadata(ResultMetadataType.ORIENTATION, rotationCount * 90);
}
else if (!result.ResultMetadata.ContainsKey(ResultMetadataType.ORIENTATION))
{
result.ResultMetadata[ResultMetadataType.ORIENTATION] = rotationCount * 90;
}
else
{
// perhaps the core decoder rotates the image already (can happen if TryHarder is specified)
result.ResultMetadata[ResultMetadataType.ORIENTATION] = ((int)(result.ResultMetadata[ResultMetadataType.ORIENTATION]) + rotationCount * 90) % 360;
}
OnResultFound(result);
}
return result;
}
protected void OnResultsFound(IEnumerable<Result> results)
{
if (ResultFound != null)
{
foreach (var result in results)
{
ResultFound(result);
}
}
}
protected void OnResultFound(Result result)
{
if (ResultFound != null)
{
ResultFound(result);
}
}
protected void OnResultPointFound(ResultPoint resultPoint)
{
if (explicitResultPointFound != null)
{
explicitResultPointFound(resultPoint);
}
}
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="rawRGB">The image as byte[] array.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="format">The format.</param>
/// <returns>
/// the result data or null
/// </returns>
public Result Decode(byte[] rawRGB, int width, int height, RGBLuminanceSource.BitmapFormat format)
{
if (rawRGB == null)
throw new ArgumentNullException("rawRGB");
var luminanceSource = createRGBLuminanceSource(rawRGB, width, height, format);
return Decode(luminanceSource);
}
}
}

+ 161
- 0
shadowsocks-csharp/3rd/zxing/IBarcodeReader.cs View File

@@ -0,0 +1,161 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
using System;
using System.Collections.Generic;
#if !(SILVERLIGHT || NETFX_CORE)
#if !UNITY
#if !PORTABLE
using System.Drawing;
#endif
#else
using UnityEngine;
#endif
#elif NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#else
using System.Windows.Media.Imaging;
#endif
using ZXing.Common;
namespace ZXing
{
/// <summary>
/// Interface for a smart class to decode the barcode inside a bitmap object
/// </summary>
public interface IBarcodeReader
{
/// <summary>
/// event is executed when a result point was found
/// </summary>
event Action<ResultPoint> ResultPointFound;
/// <summary>
/// event is executed when a result was found via decode
/// </summary>
event Action<Result> ResultFound;
/// <summary>
/// Gets or sets a flag which cause a deeper look into the bitmap
/// </summary>
/// <value>
/// <c>true</c> if [try harder]; otherwise, <c>false</c>.
/// </value>
[Obsolete("Please use the Options.TryHarder property instead.")]
bool TryHarder { get; set; }
/// <summary>
/// Image is a pure monochrome image of a barcode.
/// </summary>
/// <value>
/// <c>true</c> if monochrome image of a barcode; otherwise, <c>false</c>.
/// </value>
[Obsolete("Please use the Options.PureBarcode property instead.")]
bool PureBarcode { get; set; }
/// <summary>
/// Specifies what character encoding to use when decoding, where applicable (type String)
/// </summary>
/// <value>
/// The character set.
/// </value>
[Obsolete("Please use the Options.CharacterSet property instead.")]
string CharacterSet { get; set; }
/// <summary>
/// Image is known to be of one of a few possible formats.
/// Maps to a {@link java.util.List} of {@link BarcodeFormat}s.
/// </summary>
/// <value>
/// The possible formats.
/// </value>
[Obsolete("Please use the Options.PossibleFormats property instead.")]
IList<BarcodeFormat> PossibleFormats { get; set; }
/// <summary>
/// Specifies some options which influence the decoding process
/// </summary>
DecodingOptions Options { get; set; }
/// <summary>
/// Decodes the specified barcode bitmap which is given by a generic byte array with the order RGB24.
/// </summary>
/// <param name="rawRGB">The image as RGB24 array.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="format">The format.</param>
/// <returns>
/// the result data or null
/// </returns>
Result Decode(byte[] rawRGB, int width, int height, RGBLuminanceSource.BitmapFormat format);
/// <summary>
/// Tries to decode a barcode within an image which is given by a luminance source.
/// That method gives a chance to prepare a luminance source completely before calling
/// the time consuming decoding method. On the other hand there is a chance to create
/// a luminance source which is independent from external resources (like Bitmap objects)
/// and the decoding call can be made in a background thread.
/// </summary>
/// <param name="luminanceSource">The luminance source.</param>
/// <returns></returns>
Result Decode(LuminanceSource luminanceSource);
#if MONOTOUCH
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="barcodeBitmap">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
Result Decode(MonoTouch.UIKit.UIImage barcodeImage);
#elif MONOANDROID
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="barcodeBitmap">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
Result Decode(Android.Graphics.Bitmap barcodeImage);
#else
#if !PORTABLE
#if !(SILVERLIGHT || NETFX_CORE)
#if !UNITY
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="barcodeBitmap">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
Result Decode(Bitmap barcodeBitmap);
#else
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="rawColor32">The image as Color32 array.</param>
/// <returns>the result data or null</returns>
Result Decode(Color32[] rawColor32, int width, int height);
#endif
#else
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="barcodeBitmap">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
Result Decode(WriteableBitmap barcodeBitmap);
#endif
#endif
#endif
}
}

+ 123
- 0
shadowsocks-csharp/3rd/zxing/IBarcodeReaderGeneric.cs View File

@@ -0,0 +1,123 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
using System;
using System.Collections.Generic;
using ZXing.Common;
namespace ZXing
{
/// <summary>
/// Interface for a smart class to decode the barcode inside a bitmap object
/// </summary>
/// <typeparam name="T">gives the type of the input data</typeparam>
public interface IBarcodeReaderGeneric<T>
{
/// <summary>
/// event is executed when a result point was found
/// </summary>
event Action<ResultPoint> ResultPointFound;
/// <summary>
/// event is executed when a result was found via decode
/// </summary>
event Action<Result> ResultFound;
/// <summary>
/// Gets or sets a flag which cause a deeper look into the bitmap
/// </summary>
/// <value>
/// <c>true</c> if [try harder]; otherwise, <c>false</c>.
/// </value>
[Obsolete("Please use the Options.TryHarder property instead.")]
bool TryHarder { get; set; }
/// <summary>
/// Image is a pure monochrome image of a barcode.
/// </summary>
/// <value>
/// <c>true</c> if monochrome image of a barcode; otherwise, <c>false</c>.
/// </value>
[Obsolete("Please use the Options.PureBarcode property instead.")]
bool PureBarcode { get; set; }
/// <summary>
/// Specifies what character encoding to use when decoding, where applicable (type String)
/// </summary>
/// <value>
/// The character set.
/// </value>
[Obsolete("Please use the Options.CharacterSet property instead.")]
string CharacterSet { get; set; }
/// <summary>
/// Image is known to be of one of a few possible formats.
/// Maps to a {@link java.util.List} of {@link BarcodeFormat}s.
/// </summary>
/// <value>
/// The possible formats.
/// </value>
[Obsolete("Please use the Options.PossibleFormats property instead.")]
IList<BarcodeFormat> PossibleFormats { get; set; }
/// <summary>
/// Specifies some options which influence the decoding process
/// </summary>
DecodingOptions Options { get; set; }
/// <summary>
/// Decodes the specified barcode bitmap which is given by a generic byte array.
/// </summary>
/// <param name="rawRGB">The barcode bitmap.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="format">The format.</param>
/// <returns>
/// the result data or null
/// </returns>
Result Decode(byte[] rawRGB, int width, int height, RGBLuminanceSource.BitmapFormat format);
/// <summary>
/// Tries to decode a barcode within an image which is given by a luminance source.
/// That method gives a chance to prepare a luminance source completely before calling
/// the time consuming decoding method. On the other hand there is a chance to create
/// a luminance source which is independent from external resources (like Bitmap objects)
/// and the decoding call can be made in a background thread.
/// </summary>
/// <param name="luminanceSource">The luminance source.</param>
/// <returns></returns>
Result Decode(LuminanceSource luminanceSource);
#if !PORTABLE
#if !UNITY
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="barcodeBitmap">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
Result Decode(T barcodeBitmap);
#else
/// <summary>
/// Decodes the specified barcode bitmap.
/// </summary>
/// <param name="rawRGB">The barcode bitmap.</param>
/// <returns>the result data or null</returns>
Result Decode(T rawRGB, int width, int height);
#endif
#endif
}
}

+ 314
- 0
shadowsocks-csharp/3rd/zxing/RGBLuminanceSource.cs View File

@@ -0,0 +1,314 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
using System;
namespace ZXing
{
/// <summary>
/// Luminance source class which support different formats of images.
/// </summary>
public partial class RGBLuminanceSource : BaseLuminanceSource
{
/// <summary>
/// enumeration of supported bitmap format which the RGBLuminanceSource can process
/// </summary>
public enum BitmapFormat
{
/// <summary>
/// format of the byte[] isn't known. RGBLuminanceSource tries to determine the best possible value
/// </summary>
Unknown,
/// <summary>
/// grayscale array, the byte array is a luminance array with 1 byte per pixel
/// </summary>
Gray8,
/// <summary>
/// 3 bytes per pixel with the channels red, green and blue
/// </summary>
RGB24,
/// <summary>
/// 4 bytes per pixel with the channels red, green and blue
/// </summary>
RGB32,
/// <summary>
/// 4 bytes per pixel with the channels alpha, red, green and blue
/// </summary>
ARGB32,
/// <summary>
/// 3 bytes per pixel with the channels blue, green and red
/// </summary>
BGR24,
/// <summary>
/// 4 bytes per pixel with the channels blue, green and red
/// </summary>
BGR32,
/// <summary>
/// 4 bytes per pixel with the channels blue, green, red and alpha
/// </summary>
BGRA32,
/// <summary>
/// 2 bytes per pixel, 5 bit red, 6 bits green and 5 bits blue
/// </summary>
RGB565,
/// <summary>
/// 4 bytes per pixel with the channels red, green, blue and alpha
/// </summary>
RGBA32,
}
/// <summary>
/// Initializes a new instance of the <see cref="RGBLuminanceSource"/> class.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
protected RGBLuminanceSource(int width, int height)
: base(width, height)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RGBLuminanceSource"/> class.
/// It supports a byte array with 3 bytes per pixel (RGB24).
/// </summary>
/// <param name="rgbRawBytes">The RGB raw bytes.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
public RGBLuminanceSource(byte[] rgbRawBytes, int width, int height)
: this(rgbRawBytes, width, height, BitmapFormat.RGB24)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RGBLuminanceSource"/> class.
/// It supports a byte array with 1 byte per pixel (Gray8).
/// That means the whole array consists of the luminance values (grayscale).
/// </summary>
/// <param name="luminanceArray">The luminance array.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="is8Bit">if set to <c>true</c> [is8 bit].</param>
[Obsolete("Use RGBLuminanceSource(luminanceArray, width, height, BitmapFormat.Gray8)")]
public RGBLuminanceSource(byte[] luminanceArray, int width, int height, bool is8Bit)
: this(luminanceArray, width, height, BitmapFormat.Gray8)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RGBLuminanceSource"/> class.
/// It supports a byte array with 3 bytes per pixel (RGB24).
/// </summary>
/// <param name="rgbRawBytes">The RGB raw bytes.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="bitmapFormat">The bitmap format.</param>
public RGBLuminanceSource(byte[] rgbRawBytes, int width, int height, BitmapFormat bitmapFormat)
: base(width, height)
{
CalculateLuminance(rgbRawBytes, bitmapFormat);
}
/// <summary>
/// Should create a new luminance source with the right class type.
/// The method is used in methods crop and rotate.
/// </summary>
/// <param name="newLuminances">The new luminances.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns></returns>
protected override LuminanceSource CreateLuminanceSource(byte[] newLuminances, int width, int height)
{
return new RGBLuminanceSource(width, height) { luminances = newLuminances };
}
private static BitmapFormat DetermineBitmapFormat(byte[] rgbRawBytes, int width, int height)
{
var square = width*height;
var byteperpixel = rgbRawBytes.Length/square;
switch (byteperpixel)
{
case 1:
return BitmapFormat.Gray8;
case 2:
return BitmapFormat.RGB565;
case 3:
return BitmapFormat.RGB24;
case 4:
return BitmapFormat.RGB32;
default:
throw new ArgumentException("The bitmap format could not be determined. Please specify the correct value.");
}
}
protected void CalculateLuminance(byte[] rgbRawBytes, BitmapFormat bitmapFormat)
{
if (bitmapFormat == BitmapFormat.Unknown)
{
bitmapFormat = DetermineBitmapFormat(rgbRawBytes, Width, Height);
}
switch (bitmapFormat)
{
case BitmapFormat.Gray8:
Buffer.BlockCopy(rgbRawBytes, 0, luminances, 0, rgbRawBytes.Length < luminances.Length ? rgbRawBytes.Length : luminances.Length);
break;
case BitmapFormat.RGB24:
CalculateLuminanceRGB24(rgbRawBytes);
break;
case BitmapFormat.BGR24:
CalculateLuminanceBGR24(rgbRawBytes);
break;
case BitmapFormat.RGB32:
CalculateLuminanceRGB32(rgbRawBytes);
break;
case BitmapFormat.BGR32:
CalculateLuminanceBGR32(rgbRawBytes);
break;
case BitmapFormat.RGBA32:
CalculateLuminanceRGBA32(rgbRawBytes);
break;
case BitmapFormat.ARGB32:
CalculateLuminanceARGB32(rgbRawBytes);
break;
case BitmapFormat.BGRA32:
CalculateLuminanceBGRA32(rgbRawBytes);
break;
case BitmapFormat.RGB565:
CalculateLuminanceRGB565(rgbRawBytes);
break;
default:
throw new ArgumentException("The bitmap format isn't supported.", bitmapFormat.ToString());
}
}
private void CalculateLuminanceRGB565(byte[] rgb565RawData)
{
var luminanceIndex = 0;
for (var index = 0; index < rgb565RawData.Length && luminanceIndex < luminances.Length; index += 2, luminanceIndex++)
{
var byte1 = rgb565RawData[index];
var byte2 = rgb565RawData[index + 1];
var b5 = byte1 & 0x1F;
var g5 = (((byte1 & 0xE0) >> 5) | ((byte2 & 0x03) << 3)) & 0x1F;
var r5 = (byte2 >> 2) & 0x1F;
var r8 = (r5 * 527 + 23) >> 6;
var g8 = (g5 * 527 + 23) >> 6;
var b8 = (b5 * 527 + 23) >> 6;
// cheap, not fully accurate conversion
//var pixel = (byte2 << 8) | byte1;
//b8 = (((pixel) & 0x001F) << 3);
//g8 = (((pixel) & 0x07E0) >> 2) & 0xFF;
//r8 = (((pixel) & 0xF800) >> 8);
luminances[luminanceIndex] = (byte)((RChannelWeight * r8 + GChannelWeight * g8 + BChannelWeight * b8) >> ChannelWeight);
}
}
private void CalculateLuminanceRGB24(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
int r = rgbRawBytes[rgbIndex++];
int g = rgbRawBytes[rgbIndex++];
int b = rgbRawBytes[rgbIndex++];
luminances[luminanceIndex] = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
}
}
private void CalculateLuminanceBGR24(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
int b = rgbRawBytes[rgbIndex++];
int g = rgbRawBytes[rgbIndex++];
int r = rgbRawBytes[rgbIndex++];
luminances[luminanceIndex] = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
}
}
private void CalculateLuminanceRGB32(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
int r = rgbRawBytes[rgbIndex++];
int g = rgbRawBytes[rgbIndex++];
int b = rgbRawBytes[rgbIndex++];
rgbIndex++;
luminances[luminanceIndex] = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
}
}
private void CalculateLuminanceBGR32(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
int b = rgbRawBytes[rgbIndex++];
int g = rgbRawBytes[rgbIndex++];
int r = rgbRawBytes[rgbIndex++];
rgbIndex++;
luminances[luminanceIndex] = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
}
}
private void CalculateLuminanceBGRA32(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
var b = rgbRawBytes[rgbIndex++];
var g = rgbRawBytes[rgbIndex++];
var r = rgbRawBytes[rgbIndex++];
var alpha = rgbRawBytes[rgbIndex++];
var luminance = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
luminances[luminanceIndex] = (byte)(((luminance * alpha) >> 8) + (255 * (255 - alpha) >> 8));
}
}
private void CalculateLuminanceRGBA32(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
var r = rgbRawBytes[rgbIndex++];
var g = rgbRawBytes[rgbIndex++];
var b = rgbRawBytes[rgbIndex++];
var alpha = rgbRawBytes[rgbIndex++];
var luminance = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
luminances[luminanceIndex] = (byte)(((luminance * alpha) >> 8) + (255 * (255 - alpha) >> 8));
}
}
private void CalculateLuminanceARGB32(byte[] rgbRawBytes)
{
for (int rgbIndex = 0, luminanceIndex = 0; rgbIndex < rgbRawBytes.Length && luminanceIndex < luminances.Length; luminanceIndex++)
{
// Calculate luminance cheaply, favoring green.
var alpha = rgbRawBytes[rgbIndex++];
var r = rgbRawBytes[rgbIndex++];
var g = rgbRawBytes[rgbIndex++];
var b = rgbRawBytes[rgbIndex++];
var luminance = (byte)((RChannelWeight * r + GChannelWeight * g + BChannelWeight * b) >> ChannelWeight);
luminances[luminanceIndex] = (byte)(((luminance * alpha) >> 8) + (255 * (255 - alpha) >> 8));
}
}
}
}

+ 128
- 0
shadowsocks-csharp/3rd/zxing/common/CharacterSetECI.cs View File

@@ -0,0 +1,128 @@
/*
* Copyright 2008 ZXing authors
*
* 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.
*/
using System;
using System.Collections.Generic;
namespace ZXing.Common
{
/// <summary> Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1
/// of ISO 18004.
///
/// </summary>
/// <author>Sean Owen</author>
public sealed class CharacterSetECI : ECI
{
internal static readonly IDictionary<int, CharacterSetECI> VALUE_TO_ECI;
internal static readonly IDictionary<string, CharacterSetECI> NAME_TO_ECI;
private readonly String encodingName;
public String EncodingName
{
get
{
return encodingName;
}
}
static CharacterSetECI()
{
VALUE_TO_ECI = new Dictionary<int, CharacterSetECI>();
NAME_TO_ECI = new Dictionary<string, CharacterSetECI>();
// TODO figure out if these values are even right!
addCharacterSet(0, "CP437");
addCharacterSet(1, new[] { "ISO-8859-1", "ISO8859_1" });
addCharacterSet(2, "CP437");
addCharacterSet(3, new[] { "ISO-8859-1", "ISO8859_1" });
addCharacterSet(4, new[] { "ISO-8859-2", "ISO8859_2" });
addCharacterSet(5, new[] { "ISO-8859-3", "ISO8859_3" });
addCharacterSet(6, new[] { "ISO-8859-4", "ISO8859_4" });
addCharacterSet(7, new[] { "ISO-8859-5", "ISO8859_5" });
addCharacterSet(8, new[] { "ISO-8859-6", "ISO8859_6" });
addCharacterSet(9, new[] { "ISO-8859-7", "ISO8859_7" });
addCharacterSet(10, new[] { "ISO-8859-8", "ISO8859_8" });
addCharacterSet(11, new[] { "ISO-8859-9", "ISO8859_9" });
addCharacterSet(12, new[] { "ISO-8859-4", "ISO-8859-10", "ISO8859_10" }); // use ISO-8859-4 because ISO-8859-16 isn't supported
addCharacterSet(13, new[] { "ISO-8859-11", "ISO8859_11" });
addCharacterSet(15, new[] { "ISO-8859-13", "ISO8859_13" });
addCharacterSet(16, new[] { "ISO-8859-1", "ISO-8859-14", "ISO8859_14" }); // use ISO-8859-1 because ISO-8859-16 isn't supported
addCharacterSet(17, new[] { "ISO-8859-15", "ISO8859_15" });
addCharacterSet(18, new[] { "ISO-8859-3", "ISO-8859-16", "ISO8859_16" }); // use ISO-8859-3 because ISO-8859-16 isn't supported
addCharacterSet(20, new[] { "SJIS", "Shift_JIS" });
addCharacterSet(21, new[] { "WINDOWS-1250", "CP1250" });
addCharacterSet(22, new[] { "WINDOWS-1251", "CP1251" });
addCharacterSet(23, new[] { "WINDOWS-1252", "CP1252" });
addCharacterSet(24, new[] { "WINDOWS-1256", "CP1256" });
addCharacterSet(25, new[] { "UTF-16BE", "UNICODEBIG" });
addCharacterSet(26, new[] { "UTF-8", "UTF8" });
addCharacterSet(27, "US-ASCII");
addCharacterSet(170, "US-ASCII");
addCharacterSet(28, "BIG5");
addCharacterSet(29, new[] { "GB18030", "GB2312", "EUC_CN", "GBK" });
addCharacterSet(30, new[] { "EUC-KR", "EUC_KR" });
}
private CharacterSetECI(int value, String encodingName)
: base(value)
{
this.encodingName = encodingName;
}
private static void addCharacterSet(int value, String encodingName)
{
var eci = new CharacterSetECI(value, encodingName);
VALUE_TO_ECI[value] = eci; // can't use valueOf
NAME_TO_ECI[encodingName] = eci;
}
private static void addCharacterSet(int value, String[] encodingNames)
{
var eci = new CharacterSetECI(value, encodingNames[0]);
VALUE_TO_ECI[value] = eci; // can't use valueOf
foreach (string t in encodingNames)
{
NAME_TO_ECI[t] = eci;
}
}
/// <param name="value">character set ECI value
/// </param>
/// <returns> {@link CharacterSetECI} representing ECI of given value, or null if it is legal but
/// unsupported
/// </returns>
/// <throws> IllegalArgumentException if ECI value is invalid </throws>
public static CharacterSetECI getCharacterSetECIByValue(int value)
{
if (value < 0 || value >= 900)
{
return null;
}
return VALUE_TO_ECI[value];
}
/// <param name="name">character set ECI encoding name
/// </param>
/// <returns> {@link CharacterSetECI} representing ECI for character encoding, or null if it is legal
/// but unsupported
/// </returns>
public static CharacterSetECI getCharacterSetECIByName(String name)
{
return NAME_TO_ECI[name.ToUpper()];
}
}
}

+ 370
- 0
shadowsocks-csharp/3rd/zxing/common/DecodingOptions.cs View File

@@ -0,0 +1,370 @@
/*
* Copyright 2013 ZXing.Net authors
*
* 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.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace ZXing.Common
{
/// <summary>
/// Defines an container for encoder options
/// </summary>
[Serializable]
public class DecodingOptions
{
/// <summary>
/// Gets the data container for all options
/// </summary>
[Browsable(false)]
public IDictionary<DecodeHintType, object> Hints { get; private set; }
[field: NonSerialized]
public event Action<object, EventArgs> ValueChanged;
/// <summary>
/// Gets or sets a flag which cause a deeper look into the bitmap
/// </summary>
/// <value>
/// <c>true</c> if [try harder]; otherwise, <c>false</c>.
/// </value>
public bool TryHarder
{
get
{
if (Hints.ContainsKey(DecodeHintType.TRY_HARDER))
return (bool)Hints[DecodeHintType.TRY_HARDER];
return false;
}
set
{
if (value)
{
Hints[DecodeHintType.TRY_HARDER] = true;
}
else
{
if (Hints.ContainsKey(DecodeHintType.TRY_HARDER))
{
Hints.Remove(DecodeHintType.TRY_HARDER);
}
}
}
}
/// <summary>
/// Image is a pure monochrome image of a barcode.
/// </summary>
/// <value>
/// <c>true</c> if monochrome image of a barcode; otherwise, <c>false</c>.
/// </value>
public bool PureBarcode
{
get
{
if (Hints.ContainsKey(DecodeHintType.PURE_BARCODE))
return (bool)Hints[DecodeHintType.PURE_BARCODE];
return false;
}
set
{
if (value)
{
Hints[DecodeHintType.PURE_BARCODE] = true;
}
else
{
if (Hints.ContainsKey(DecodeHintType.PURE_BARCODE))
{
Hints.Remove(DecodeHintType.PURE_BARCODE);
}
}
}
}
/// <summary>
/// Specifies what character encoding to use when decoding, where applicable (type String)
/// </summary>
/// <value>
/// The character set.
/// </value>
public string CharacterSet
{
get
{
if (Hints.ContainsKey(DecodeHintType.CHARACTER_SET))
return (string)Hints[DecodeHintType.CHARACTER_SET];
return null;
}
set
{
if (value != null)
{
Hints[DecodeHintType.CHARACTER_SET] = value;
}
else
{
if (Hints.ContainsKey(DecodeHintType.CHARACTER_SET))
{
Hints.Remove(DecodeHintType.CHARACTER_SET);
}
}
}
}
/// <summary>
/// Image is known to be of one of a few possible formats.
/// Maps to a {@link java.util.List} of {@link BarcodeFormat}s.
/// </summary>
/// <value>
/// The possible formats.
/// </value>
public IList<BarcodeFormat> PossibleFormats
{
get
{
if (Hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS))
return (IList<BarcodeFormat>)Hints[DecodeHintType.POSSIBLE_FORMATS];
return null;
}
set
{
if (value != null)
{
Hints[DecodeHintType.POSSIBLE_FORMATS] = value;
}
else
{
if (Hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS))
{
Hints.Remove(DecodeHintType.POSSIBLE_FORMATS);
}
}
}
}
/// <summary>
/// if Code39 could be detected try to use extended mode for full ASCII character set
/// </summary>
public bool UseCode39ExtendedMode
{
get
{
if (Hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE))
return (bool)Hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE];
return false;
}
set
{
if (value)
{
Hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE] = true;
}
else
{
if (Hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE))
{
Hints.Remove(DecodeHintType.USE_CODE_39_EXTENDED_MODE);
}
}
}
}
/// <summary>
/// Don't fail if a Code39 is detected but can't be decoded in extended mode.
/// Return the raw Code39 result instead. Maps to <see cref="bool" />.
/// </summary>
public bool UseCode39RelaxedExtendedMode
{
get
{
if (Hints.ContainsKey(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE))
return (bool)Hints[DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE];
return false;
}
set
{
if (value)
{
Hints[DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE] = true;
}
else
{
if (Hints.ContainsKey(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE))
{
Hints.Remove(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE);
}
}
}
}
/// <summary>
/// If true, return the start and end digits in a Codabar barcode instead of stripping them. They
/// are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
/// to not be. Doesn't matter what it maps to; use <see cref="bool" />.
/// </summary>
public bool ReturnCodabarStartEnd
{
get
{
if (Hints.ContainsKey(DecodeHintType.RETURN_CODABAR_START_END))
return (bool)Hints[DecodeHintType.RETURN_CODABAR_START_END];
return false;
}
set
{
if (value)
{
Hints[DecodeHintType.RETURN_CODABAR_START_END] = true;
}
else
{
if (Hints.ContainsKey(DecodeHintType.RETURN_CODABAR_START_END))
{
Hints.Remove(DecodeHintType.RETURN_CODABAR_START_END);
}
}
}
}
/// <summary>
/// Initializes a new instance of the <see cref="EncodingOptions"/> class.
/// </summary>
public DecodingOptions()
{
var hints = new ChangeNotifyDictionary<DecodeHintType, object>();
Hints = hints;
UseCode39ExtendedMode = true;
UseCode39RelaxedExtendedMode = true;
hints.ValueChanged += (o, args) => { if (ValueChanged != null) ValueChanged(this, EventArgs.Empty); };
}
[Serializable]
private class ChangeNotifyDictionary<TKey, TValue>: IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> values;
[field: NonSerialized]
public event Action<object, EventArgs> ValueChanged;
public ChangeNotifyDictionary()
{
values = new Dictionary<TKey, TValue>();
}
private void OnValueChanged()
{
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
public void Add(TKey key, TValue value)
{
values.Add(key, value);
OnValueChanged();
}
public bool ContainsKey(TKey key)
{
return values.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get { return values.Keys; }
}
public bool Remove(TKey key)
{
var result = values.Remove(key);
OnValueChanged();
return result;
}
public bool TryGetValue(TKey key, out TValue value)
{
return values.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get { return values.Values; }
}
public TValue this[TKey key]
{
get
{
return values[key];
}
set
{
values[key] = value;
OnValueChanged();
}
}
public void Add(KeyValuePair<TKey, TValue> item)
{
values.Add(item);
OnValueChanged();
}
public void Clear()
{
values.Clear();
OnValueChanged();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return values.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
values.CopyTo(array, arrayIndex);
}
public int Count
{
get { return values.Count; }
}
public bool IsReadOnly
{
get { return values.IsReadOnly; }
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
var result = values.Remove(item);
OnValueChanged();
return result;
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((System.Collections.IEnumerable)values).GetEnumerator();
}
}
}
}

+ 66
- 0
shadowsocks-csharp/3rd/zxing/common/ECI.cs View File

@@ -0,0 +1,66 @@
/*
* Copyright 2008 ZXing authors
*
* 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.
*/
using System;
namespace ZXing.Common
{
/// <summary> Superclass of classes encapsulating types ECIs, according to "Extended Channel Interpretations"
/// 5.3 of ISO 18004.
///
/// </summary>
/// <author> Sean Owen
/// </author>
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
/// </author>
public abstract class ECI
{
virtual public int Value
{
get
{
return value_Renamed;
}
}
//UPGRADE_NOTE: Final was removed from the declaration of 'value '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
private int value_Renamed;
internal ECI(int value_Renamed)
{
this.value_Renamed = value_Renamed;
}
/// <param name="value">ECI value
/// </param>
/// <returns> {@link ECI} representing ECI of given value, or null if it is legal but unsupported
/// </returns>
/// <throws> IllegalArgumentException if ECI value is invalid </throws>
public static ECI getECIByValue(int value_Renamed)
{
if (value_Renamed < 0 || value_Renamed > 999999)
{
throw new System.ArgumentException("Bad ECI value: " + value_Renamed);
}
if (value_Renamed < 900)
{
// Character set ECIs use 000000 - 000899
return CharacterSetECI.getCharacterSetECIByValue(value_Renamed);
}
return null;
}
}
}

+ 243
- 0
shadowsocks-csharp/3rd/zxing/common/GlobalHistogramBinarizer.cs View File

@@ -0,0 +1,243 @@
/*
* Copyright 2009 ZXing authors
*
* 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.
*/
namespace ZXing.Common
{
/// <summary> This Binarizer implementation uses the old ZXing global histogram approach. It is suitable
/// for low-end mobile devices which don't have enough CPU or memory to use a local thresholding
/// algorithm. However, because it picks a global black point, it cannot handle difficult shadows
/// and gradients.
///
/// Faster mobile devices and all desktop applications should probably use HybridBinarizer instead.
///
/// <author>dswitkin@google.com (Daniel Switkin)</author>
/// <author>Sean Owen</author>
/// </summary>
public class GlobalHistogramBinarizer : Binarizer
{
private const int LUMINANCE_BITS = 5;
private const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
private const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
private static readonly byte[] EMPTY = new byte[0];
private byte[] luminances;
private readonly int[] buckets;
/// <summary>
/// Initializes a new instance of the <see cref="GlobalHistogramBinarizer"/> class.
/// </summary>
/// <param name="source">The source.</param>
public GlobalHistogramBinarizer(LuminanceSource source)
: base(source)
{
luminances = EMPTY;
buckets = new int[LUMINANCE_BUCKETS];
}
/// <summary>
/// Applies simple sharpening to the row data to improve performance of the 1D Readers.
/// </summary>
/// <param name="y"></param>
/// <param name="row"></param>
/// <returns></returns>
public override BitArray getBlackRow(int y, BitArray row)
{
LuminanceSource source = LuminanceSource;
int width = source.Width;
if (row == null || row.Size < width)
{
row = new BitArray(width);
}
else
{
row.clear();
}
initArrays(width);
byte[] localLuminances = source.getRow(y, luminances);
int[] localBuckets = buckets;
for (int x = 0; x < width; x++)
{
int pixel = localLuminances[x] & 0xff;
localBuckets[pixel >> LUMINANCE_SHIFT]++;
}
int blackPoint;
if (!estimateBlackPoint(localBuckets, out blackPoint))
return null;
int left = localLuminances[0] & 0xff;
int center = localLuminances[1] & 0xff;
for (int x = 1; x < width - 1; x++)
{
int right = localLuminances[x + 1] & 0xff;
// A simple -1 4 -1 box filter with a weight of 2.
int luminance = ((center << 2) - left - right) >> 1;
row[x] = (luminance < blackPoint);
left = center;
center = right;
}
return row;
}
/// <summary>
/// Does not sharpen the data, as this call is intended to only be used by 2D Readers.
/// </summary>
override public BitMatrix BlackMatrix
{
get
{
LuminanceSource source = LuminanceSource;
byte[] localLuminances;
int width = source.Width;
int height = source.Height;
BitMatrix matrix = new BitMatrix(width, height);
// Quickly calculates the histogram by sampling four rows from the image. This proved to be
// more robust on the blackbox tests than sampling a diagonal as we used to do.
initArrays(width);
int[] localBuckets = buckets;
for (int y = 1; y < 5; y++)
{
int row = height * y / 5;
localLuminances = source.getRow(row, luminances);
int right = (width << 2) / 5;
for (int x = width / 5; x < right; x++)
{
int pixel = localLuminances[x] & 0xff;
localBuckets[pixel >> LUMINANCE_SHIFT]++;
}
}
int blackPoint;
if (!estimateBlackPoint(localBuckets, out blackPoint))
return null;
// We delay reading the entire image luminance until the black point estimation succeeds.
// Although we end up reading four rows twice, it is consistent with our motto of
// "fail quickly" which is necessary for continuous scanning.
localLuminances = source.Matrix;
for (int y = 0; y < height; y++)
{
int offset = y * width;
for (int x = 0; x < width; x++)
{
int pixel = localLuminances[offset + x] & 0xff;
matrix[x, y] = (pixel < blackPoint);
}
}
return matrix;
}
}
/// <summary>
/// Creates a new object with the same type as this Binarizer implementation, but with pristine
/// state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache
/// of 1 bit data. See Effective Java for why we can't use Java's clone() method.
/// </summary>
/// <param name="source">The LuminanceSource this Binarizer will operate on.</param>
/// <returns>
/// A new concrete Binarizer implementation object.
/// </returns>
public override Binarizer createBinarizer(LuminanceSource source)
{
return new GlobalHistogramBinarizer(source);
}
private void initArrays(int luminanceSize)
{
if (luminances.Length < luminanceSize)
{
luminances = new byte[luminanceSize];
}
for (int x = 0; x < LUMINANCE_BUCKETS; x++)
{
buckets[x] = 0;
}
}
private static bool estimateBlackPoint(int[] buckets, out int blackPoint)
{
blackPoint = 0;
// Find the tallest peak in the histogram.
int numBuckets = buckets.Length;
int maxBucketCount = 0;
int firstPeak = 0;
int firstPeakSize = 0;
for (int x = 0; x < numBuckets; x++)
{
if (buckets[x] > firstPeakSize)
{
firstPeak = x;
firstPeakSize = buckets[x];
}
if (buckets[x] > maxBucketCount)
{
maxBucketCount = buckets[x];
}
}
// Find the second-tallest peak which is somewhat far from the tallest peak.
int secondPeak = 0;
int secondPeakScore = 0;
for (int x = 0; x < numBuckets; x++)
{
int distanceToBiggest = x - firstPeak;
// Encourage more distant second peaks by multiplying by square of distance.
int score = buckets[x] * distanceToBiggest * distanceToBiggest;
if (score > secondPeakScore)
{
secondPeak = x;
secondPeakScore = score;
}
}
// Make sure firstPeak corresponds to the black peak.
if (firstPeak > secondPeak)
{
int temp = firstPeak;
firstPeak = secondPeak;
secondPeak = temp;
}
// If there is too little contrast in the image to pick a meaningful black point, throw rather
// than waste time trying to decode the image, and risk false positives.
// TODO: It might be worth comparing the brightest and darkest pixels seen, rather than the
// two peaks, to determine the contrast.
if (secondPeak - firstPeak <= numBuckets >> 4)
{
return false;
}
// Find a valley between them that is low and closer to the white peak.
int bestValley = secondPeak - 1;
int bestValleyScore = -1;
for (int x = secondPeak - 1; x > firstPeak; x--)
{
int fromFirst = x - firstPeak;
int score = fromFirst*fromFirst*(secondPeak - x)*(maxBucketCount - buckets[x]);
if (score > bestValleyScore)
{
bestValley = x;
bestValleyScore = score;
}
}
blackPoint = bestValley << LUMINANCE_SHIFT;
return true;
}
}
}

+ 288
- 0
shadowsocks-csharp/3rd/zxing/common/HybridBinarizer.cs View File

@@ -0,0 +1,288 @@
/*
* Copyright 2009 ZXing authors
*
* 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.
*/
namespace ZXing.Common
{
/// <summary> This class implements a local thresholding algorithm, which while slower than the
/// GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
/// high frequency images of barcodes with black data on white backgrounds. For this application,
/// it does a much better job than a global blackpoint with severe shadows and gradients.
/// However it tends to produce artifacts on lower frequency images and is therefore not
/// a good general purpose binarizer for uses outside ZXing.
///
/// This class extends GlobalHistogramBinarizer, using the older histogram approach for 1D readers,
/// and the newer local approach for 2D readers. 1D decoding using a per-row histogram is already
/// inherently local, and only fails for horizontal gradients. We can revisit that problem later,
/// but for now it was not a win to use local blocks for 1D.
///
/// This Binarizer is the default for the unit tests and the recommended class for library users.
///
/// </summary>
/// <author> dswitkin@google.com (Daniel Switkin)
/// </author>
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
/// </author>
public sealed class HybridBinarizer : GlobalHistogramBinarizer
{
override public BitMatrix BlackMatrix
{
get
{
binarizeEntireImage();
return matrix;
}
}
// This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
// So this is the smallest dimension in each axis we can accept.
private const int BLOCK_SIZE_POWER = 3;
private const int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER; // ...0100...00
private const int BLOCK_SIZE_MASK = BLOCK_SIZE - 1; // ...0011...11
private const int MINIMUM_DIMENSION = 40;
private const int MIN_DYNAMIC_RANGE = 24;
private BitMatrix matrix = null;
public HybridBinarizer(LuminanceSource source)
: base(source)
{
}
public override Binarizer createBinarizer(LuminanceSource source)
{
return new HybridBinarizer(source);
}
/// <summary>
/// Calculates the final BitMatrix once for all requests. This could be called once from the
/// constructor instead, but there are some advantages to doing it lazily, such as making
/// profiling easier, and not doing heavy lifting when callers don't expect it.
/// </summary>
private void binarizeEntireImage()
{
if (matrix == null)
{
LuminanceSource source = LuminanceSource;
int width = source.Width;
int height = source.Height;
if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION)
{
byte[] luminances = source.Matrix;
int subWidth = width >> BLOCK_SIZE_POWER;
if ((width & BLOCK_SIZE_MASK) != 0)
{
subWidth++;
}
int subHeight = height >> BLOCK_SIZE_POWER;
if ((height & BLOCK_SIZE_MASK) != 0)
{
subHeight++;
}
int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
var newMatrix = new BitMatrix(width, height);
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
matrix = newMatrix;
}
else
{
// If the image is too small, fall back to the global histogram approach.
matrix = base.BlackMatrix;
}
}
}
/// <summary>
/// For each 8x8 block in the image, calculate the average black point using a 5x5 grid
/// of the blocks around it. Also handles the corner cases (fractional blocks are computed based
/// on the last 8 pixels in the row/column which are also used in the previous block).
/// </summary>
/// <param name="luminances">The luminances.</param>
/// <param name="subWidth">Width of the sub.</param>
/// <param name="subHeight">Height of the sub.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="blackPoints">The black points.</param>
/// <param name="matrix">The matrix.</param>
private static void calculateThresholdForBlock(byte[] luminances, int subWidth, int subHeight, int width, int height, int[][] blackPoints, BitMatrix matrix)
{
for (int y = 0; y < subHeight; y++)
{
int yoffset = y << BLOCK_SIZE_POWER;
int maxYOffset = height - BLOCK_SIZE;
if (yoffset > maxYOffset)
{
yoffset = maxYOffset;
}
for (int x = 0; x < subWidth; x++)
{
int xoffset = x << BLOCK_SIZE_POWER;
int maxXOffset = width - BLOCK_SIZE;
if (xoffset > maxXOffset)
{
xoffset = maxXOffset;
}
int left = cap(x, 2, subWidth - 3);
int top = cap(y, 2, subHeight - 3);
int sum = 0;
for (int z = -2; z <= 2; z++)
{
int[] blackRow = blackPoints[top + z];
sum += blackRow[left - 2];
sum += blackRow[left - 1];
sum += blackRow[left];
sum += blackRow[left + 1];
sum += blackRow[left + 2];
}
int average = sum / 25;
thresholdBlock(luminances, xoffset, yoffset, average, width, matrix);
}
}
}
private static int cap(int value, int min, int max)
{
return value < min ? min : value > max ? max : value;
}
/// <summary>
/// Applies a single threshold to an 8x8 block of pixels.
/// </summary>
/// <param name="luminances">The luminances.</param>
/// <param name="xoffset">The xoffset.</param>
/// <param name="yoffset">The yoffset.</param>
/// <param name="threshold">The threshold.</param>
/// <param name="stride">The stride.</param>
/// <param name="matrix">The matrix.</param>
private static void thresholdBlock(byte[] luminances, int xoffset, int yoffset, int threshold, int stride, BitMatrix matrix)
{
int offset = (yoffset * stride) + xoffset;
for (int y = 0; y < BLOCK_SIZE; y++, offset += stride)
{
for (int x = 0; x < BLOCK_SIZE; x++)
{
int pixel = luminances[offset + x] & 0xff;
// Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
matrix[xoffset + x, yoffset + y] = (pixel <= threshold);
}
}
}
/// <summary>
/// Calculates a single black point for each 8x8 block of pixels and saves it away.
/// See the following thread for a discussion of this algorithm:
/// http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
/// </summary>
/// <param name="luminances">The luminances.</param>
/// <param name="subWidth">Width of the sub.</param>
/// <param name="subHeight">Height of the sub.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns></returns>
private static int[][] calculateBlackPoints(byte[] luminances, int subWidth, int subHeight, int width, int height)
{
int[][] blackPoints = new int[subHeight][];
for (int i = 0; i < subHeight; i++)
{
blackPoints[i] = new int[subWidth];
}
for (int y = 0; y < subHeight; y++)
{
int yoffset = y << BLOCK_SIZE_POWER;
int maxYOffset = height - BLOCK_SIZE;
if (yoffset > maxYOffset)
{
yoffset = maxYOffset;
}
for (int x = 0; x < subWidth; x++)
{
int xoffset = x << BLOCK_SIZE_POWER;
int maxXOffset = width - BLOCK_SIZE;
if (xoffset > maxXOffset)
{
xoffset = maxXOffset;
}
int sum = 0;
int min = 0xFF;
int max = 0;
for (int yy = 0, offset = yoffset * width + xoffset; yy < BLOCK_SIZE; yy++, offset += width)
{
for (int xx = 0; xx < BLOCK_SIZE; xx++)
{
int pixel = luminances[offset + xx] & 0xFF;
// still looking for good contrast
sum += pixel;
if (pixel < min)
{
min = pixel;
}
if (pixel > max)
{
max = pixel;
}
}
// short-circuit min/max tests once dynamic range is met
if (max - min > MIN_DYNAMIC_RANGE)
{
// finish the rest of the rows quickly
for (yy++, offset += width; yy < BLOCK_SIZE; yy++, offset += width)
{
for (int xx = 0; xx < BLOCK_SIZE; xx++)
{
sum += luminances[offset + xx] & 0xFF;
}
}
}
}
// The default estimate is the average of the values in the block.
int average = sum >> (BLOCK_SIZE_POWER * 2);
if (max - min <= MIN_DYNAMIC_RANGE)
{
// If variation within the block is low, assume this is a block with only light or only
// dark pixels. In that case we do not want to use the average, as it would divide this
// low contrast area into black and white pixels, essentially creating data out of noise.
//
// The default assumption is that the block is light/background. Since no estimate for
// the level of dark pixels exists locally, use half the min for the block.
average = min >> 1;
if (y > 0 && x > 0)
{
// Correct the "white background" assumption for blocks that have neighbors by comparing
// the pixels in this block to the previously calculated black points. This is based on
// the fact that dark barcode symbology is always surrounded by some amount of light
// background for which reasonable black point estimates were made. The bp estimated at
// the boundaries is used for the interior.
// The (min < bp) is arbitrary but works better than other heuristics that were tried.
int averageNeighborBlackPoint = (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) +
blackPoints[y - 1][x - 1]) >> 2;
if (min < averageNeighborBlackPoint)
{
average = averageNeighborBlackPoint;
}
}
}
blackPoints[y][x] = average;
}
}
return blackPoints;
}
}
}

+ 266
- 0
shadowsocks-csharp/3rd/zxing/common/StringUtils.cs View File

@@ -0,0 +1,266 @@
/*
* Copyright (C) 2010 ZXing authors
*
* 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ZXing.Common
{
/// <summary>
/// Common string-related functions.
/// </summary>
/// <author>Sean Owen</author>
/// <author>Alex Dupre</author>
public static class StringUtils
{
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || WINDOWS_PHONE80 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE)
private const String PLATFORM_DEFAULT_ENCODING = "UTF-8";
#else
private static String PLATFORM_DEFAULT_ENCODING = Encoding.Default.WebName;
#endif
public static String SHIFT_JIS = "SJIS";
public static String GB2312 = "GB2312";
private const String EUC_JP = "EUC-JP";
private const String UTF8 = "UTF-8";
private const String ISO88591 = "ISO-8859-1";
private static readonly bool ASSUME_SHIFT_JIS =
String.Compare(SHIFT_JIS, PLATFORM_DEFAULT_ENCODING, StringComparison.OrdinalIgnoreCase) == 0 ||
String.Compare(EUC_JP, PLATFORM_DEFAULT_ENCODING, StringComparison.OrdinalIgnoreCase) == 0;
/// <summary>
/// Guesses the encoding.
/// </summary>
/// <param name="bytes">bytes encoding a string, whose encoding should be guessed</param>
/// <param name="hints">decode hints if applicable</param>
/// <returns>name of guessed encoding; at the moment will only guess one of:
/// {@link #SHIFT_JIS}, {@link #UTF8}, {@link #ISO88591}, or the platform
/// default encoding if none of these can possibly be correct</returns>
public static String guessEncoding(byte[] bytes, IDictionary<DecodeHintType, object> hints)
{
if (hints != null && hints.ContainsKey(DecodeHintType.CHARACTER_SET))
{
String characterSet = (String)hints[DecodeHintType.CHARACTER_SET];
if (characterSet != null)
{
return characterSet;
}
}
// For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,
// which should be by far the most common encodings.
int length = bytes.Length;
bool canBeISO88591 = true;
bool canBeShiftJIS = true;
bool canBeUTF8 = true;
int utf8BytesLeft = 0;
//int utf8LowChars = 0;
int utf2BytesChars = 0;
int utf3BytesChars = 0;
int utf4BytesChars = 0;
int sjisBytesLeft = 0;
//int sjisLowChars = 0;
int sjisKatakanaChars = 0;
//int sjisDoubleBytesChars = 0;
int sjisCurKatakanaWordLength = 0;
int sjisCurDoubleBytesWordLength = 0;
int sjisMaxKatakanaWordLength = 0;
int sjisMaxDoubleBytesWordLength = 0;
//int isoLowChars = 0;
//int isoHighChars = 0;
int isoHighOther = 0;
bool utf8bom = bytes.Length > 3 &&
bytes[0] == 0xEF &&
bytes[1] == 0xBB &&
bytes[2] == 0xBF;
for (int i = 0;
i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);
i++)
{
int value = bytes[i] & 0xFF;
// UTF-8 stuff
if (canBeUTF8)
{
if (utf8BytesLeft > 0)
{
if ((value & 0x80) == 0)
{
canBeUTF8 = false;
}
else
{
utf8BytesLeft--;
}
}
else if ((value & 0x80) != 0)
{
if ((value & 0x40) == 0)
{
canBeUTF8 = false;
}
else
{
utf8BytesLeft++;
if ((value & 0x20) == 0)
{
utf2BytesChars++;
}
else
{
utf8BytesLeft++;
if ((value & 0x10) == 0)
{
utf3BytesChars++;
}
else
{
utf8BytesLeft++;
if ((value & 0x08) == 0)
{
utf4BytesChars++;
}
else
{
canBeUTF8 = false;
}
}
}
}
} //else {
//utf8LowChars++;
//}
}
// ISO-8859-1 stuff
if (canBeISO88591)
{
if (value > 0x7F && value < 0xA0)
{
canBeISO88591 = false;
}
else if (value > 0x9F)
{
if (value < 0xC0 || value == 0xD7 || value == 0xF7)
{
isoHighOther++;
} //else {
//isoHighChars++;
//}
} //else {
//isoLowChars++;
//}
}
// Shift_JIS stuff
if (canBeShiftJIS)
{
if (sjisBytesLeft > 0)
{
if (value < 0x40 || value == 0x7F || value > 0xFC)
{
canBeShiftJIS = false;
}
else
{
sjisBytesLeft--;
}
}
else if (value == 0x80 || value == 0xA0 || value > 0xEF)
{
canBeShiftJIS = false;
}
else if (value > 0xA0 && value < 0xE0)
{
sjisKatakanaChars++;
sjisCurDoubleBytesWordLength = 0;
sjisCurKatakanaWordLength++;
if (sjisCurKatakanaWordLength > sjisMaxKatakanaWordLength)
{
sjisMaxKatakanaWordLength = sjisCurKatakanaWordLength;
}
}
else if (value > 0x7F)
{
sjisBytesLeft++;
//sjisDoubleBytesChars++;
sjisCurKatakanaWordLength = 0;
sjisCurDoubleBytesWordLength++;
if (sjisCurDoubleBytesWordLength > sjisMaxDoubleBytesWordLength)
{
sjisMaxDoubleBytesWordLength = sjisCurDoubleBytesWordLength;
}
}
else
{
//sjisLowChars++;
sjisCurKatakanaWordLength = 0;
sjisCurDoubleBytesWordLength = 0;
}
}
}
if (canBeUTF8 && utf8BytesLeft > 0)
{
canBeUTF8 = false;
}
if (canBeShiftJIS && sjisBytesLeft > 0)
{
canBeShiftJIS = false;
}
// Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done
if (canBeUTF8 && (utf8bom || utf2BytesChars + utf3BytesChars + utf4BytesChars > 0))
{
return UTF8;
}
// Easy -- if assuming Shift_JIS or at least 3 valid consecutive not-ascii characters (and no evidence it can't be), done
if (canBeShiftJIS && (ASSUME_SHIFT_JIS || sjisMaxKatakanaWordLength >= 3 || sjisMaxDoubleBytesWordLength >= 3))
{
return SHIFT_JIS;
}
// Distinguishing Shift_JIS and ISO-8859-1 can be a little tough for short words. The crude heuristic is:
// - If we saw
// - only two consecutive katakana chars in the whole text, or
// - at least 10% of bytes that could be "upper" not-alphanumeric Latin1,
// - then we conclude Shift_JIS, else ISO-8859-1
if (canBeISO88591 && canBeShiftJIS)
{
return (sjisMaxKatakanaWordLength == 2 && sjisKatakanaChars == 2) || isoHighOther * 10 >= length
? SHIFT_JIS : ISO88591;
}
// Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding
if (canBeISO88591)
{
return ISO88591;
}
if (canBeShiftJIS)
{
return SHIFT_JIS;
}
if (canBeUTF8)
{
return UTF8;
}
// Otherwise, we take a wild guess with platform encoding
return PLATFORM_DEFAULT_ENCODING;
}
}
}

+ 102
- 0
shadowsocks-csharp/3rd/zxing/net2.0/Action.cs View File

@@ -0,0 +1,102 @@
/*
* Copyright 2013 ZXing.Net authors
*
* 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.
*/
namespace ZXing
{
#if !WindowsCE
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
public delegate void Action();
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <param name="param1">The param1.</param>
public delegate void Action<in T1>(T1 param1);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
public delegate void Action<in T1, in T2>(T1 param1, T2 param2);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
public delegate void Action<in T1, in T2, in T3>(T1 param1, T2 param2, T3 param3);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <typeparam name="T4">The type of the 4.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
/// <param name="param4">The param4.</param>
public delegate void Action<in T1, in T2, in T3, in T4>(T1 param1, T2 param2, T3 param3, T4 param4);
#else
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
public delegate void Action();
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <param name="param1">The param1.</param>
public delegate void Action<T1>(T1 param1);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
public delegate void Action<T1, T2>(T1 param1, T2 param2);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
public delegate void Action<T1, T2, T3>(T1 param1, T2 param2, T3 param3);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <typeparam name="T4">The type of the 4.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
/// <param name="param4">The param4.</param>
public delegate void Action<T1, T2, T3, T4>(T1 param1, T2 param2, T3 param3, T4 param4);
#endif
}

+ 122
- 0
shadowsocks-csharp/3rd/zxing/net2.0/Func.cs View File

@@ -0,0 +1,122 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
namespace ZXing
{
#if !WindowsCE
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <returns></returns>
public delegate TResult Func<out TResult>();
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <returns></returns>
public delegate TResult Func<in T1, out TResult>(T1 param1);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <returns></returns>
public delegate TResult Func<in T1, in T2, out TResult>(T1 param1, T2 param2);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
/// <returns></returns>
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 param1, T2 param2, T3 param3);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <typeparam name="T4">The type of the 4.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
/// <param name="param4">The param4.</param>
/// <returns></returns>
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 param1, T2 param2, T3 param3, T4 param4);
#else
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <returns></returns>
public delegate TResult Func<TResult>();
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <returns></returns>
public delegate TResult Func<T1, TResult>(T1 param1);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <returns></returns>
public delegate TResult Func<T1, T2, TResult>(T1 param1, T2 param2);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
/// <returns></returns>
public delegate TResult Func<T1, T2, T3, TResult>(T1 param1, T2 param2, T3 param3);
/// <summary>
/// for compatibility with .net 4.0
/// </summary>
/// <typeparam name="T1">The type of the 1.</typeparam>
/// <typeparam name="T2">The type of the 2.</typeparam>
/// <typeparam name="T3">The type of the 3.</typeparam>
/// <typeparam name="T4">The type of the 4.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="param1">The param1.</param>
/// <param name="param2">The param2.</param>
/// <param name="param3">The param3.</param>
/// <param name="param4">The param4.</param>
/// <returns></returns>
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 param1, T2 param2, T3 param3, T4 param4);
#endif
}

+ 29
- 0
shadowsocks-csharp/3rd/zxing/net2.0/TimeZoneInfo.cs View File

@@ -0,0 +1,29 @@
/*
* Copyright 2012 ZXing.Net authors
*
* 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.
*/
namespace System
{
internal class TimeZoneInfo
{
internal static TimeZoneInfo Local = null;
internal static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone)
{
// TODO: fix it for .net 2.0
return dateTime;
}
}
}

+ 234
- 3
shadowsocks-csharp/3rd/zxing/qrcode/decoder/DecodedBitStreamParser.cs View File

@@ -54,7 +54,7 @@ namespace ZXing.QrCode.Internal
try try
{ {
//CharacterSetECI currentCharacterSetECI = null;
CharacterSetECI currentCharacterSetECI = null;
bool fc1InEffect = false; bool fc1InEffect = false;
Mode mode; Mode mode;
do do
@@ -94,14 +94,29 @@ namespace ZXing.QrCode.Internal
symbolSequence = bits.readBits(8); symbolSequence = bits.readBits(8);
parityData = bits.readBits(8); parityData = bits.readBits(8);
} }
else if (mode == Mode.ECI)
{
// Count doesn't apply to ECI
int value = parseECIValue(bits);
currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
if (currentCharacterSetECI == null)
{
return null;
}
}
else else
{ {
// First handle Hanzi mode which does not start with character count // First handle Hanzi mode which does not start with character count
if (mode == Mode.HANZI) if (mode == Mode.HANZI)
{ {
//chinese mode contains a sub set indicator right after mode indicator //chinese mode contains a sub set indicator right after mode indicator
//int subset = bits.readBits(4);
//int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
int subset = bits.readBits(4);
int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
if (subset == GB2312_SUBSET)
{
if (!decodeHanziSegment(bits, result, countHanzi))
return null;
}
} }
else else
{ {
@@ -118,6 +133,16 @@ namespace ZXing.QrCode.Internal
if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect)) if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect))
return null; return null;
} }
else if (mode == Mode.BYTE)
{
if (!decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints))
return null;
}
else if (mode == Mode.KANJI)
{
if (!decodeKanjiSegment(bits, result, count))
return null;
}
else else
{ {
return null; return null;
@@ -145,8 +170,214 @@ namespace ZXing.QrCode.Internal
symbolSequence, parityData); symbolSequence, parityData);
} }
/// <summary>
/// See specification GBT 18284-2000
/// </summary>
/// <param name="bits">The bits.</param>
/// <param name="result">The result.</param>
/// <param name="count">The count.</param>
/// <returns></returns>
private static bool decodeHanziSegment(BitSource bits,
StringBuilder result,
int count)
{
// Don't crash trying to read more bits than we have available.
if (count * 13 > bits.available())
{
return false;
}
// Each character will require 2 bytes. Read the characters as 2-byte pairs
// and decode as GB2312 afterwards
byte[] buffer = new byte[2 * count];
int offset = 0;
while (count > 0)
{
// Each 13 bits encodes a 2-byte character
int twoBytes = bits.readBits(13);
int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
if (assembledTwoBytes < 0x003BF)
{
// In the 0xA1A1 to 0xAAFE range
assembledTwoBytes += 0x0A1A1;
}
else
{
// In the 0xB0A1 to 0xFAFE range
assembledTwoBytes += 0x0A6A1;
}
buffer[offset] = (byte)((assembledTwoBytes >> 8) & 0xFF);
buffer[offset + 1] = (byte)(assembledTwoBytes & 0xFF);
offset += 2;
count--;
}
try
{
result.Append(Encoding.GetEncoding(StringUtils.GB2312).GetString(buffer, 0, buffer.Length));
}
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || MONOANDROID || MONOTOUCH)
catch (ArgumentException)
{
try
{
// Silverlight only supports a limited number of character sets, trying fallback to UTF-8
result.Append(Encoding.GetEncoding("UTF-8").GetString(buffer, 0, buffer.Length));
}
catch (Exception)
{
return false;
}
}
#endif
catch (Exception)
{
return false;
}
return true;
}
private static bool decodeKanjiSegment(BitSource bits,
StringBuilder result,
int count)
{
// Don't crash trying to read more bits than we have available.
if (count * 13 > bits.available())
{
return false;
}
// Each character will require 2 bytes. Read the characters as 2-byte pairs
// and decode as Shift_JIS afterwards
byte[] buffer = new byte[2 * count];
int offset = 0;
while (count > 0)
{
// Each 13 bits encodes a 2-byte character
int twoBytes = bits.readBits(13);
int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
if (assembledTwoBytes < 0x01F00)
{
// In the 0x8140 to 0x9FFC range
assembledTwoBytes += 0x08140;
}
else
{
// In the 0xE040 to 0xEBBF range
assembledTwoBytes += 0x0C140;
}
buffer[offset] = (byte)(assembledTwoBytes >> 8);
buffer[offset + 1] = (byte)assembledTwoBytes;
offset += 2;
count--;
}
// Shift_JIS may not be supported in some environments:
try
{
result.Append(Encoding.GetEncoding(StringUtils.SHIFT_JIS).GetString(buffer, 0, buffer.Length));
}
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || MONOANDROID || MONOTOUCH)
catch (ArgumentException)
{
try
{
// Silverlight only supports a limited number of character sets, trying fallback to UTF-8
result.Append(Encoding.GetEncoding("UTF-8").GetString(buffer, 0, buffer.Length));
}
catch (Exception)
{
return false;
}
}
#endif
catch (Exception)
{
return false;
}
return true;
}
private static bool decodeByteSegment(BitSource bits,
StringBuilder result,
int count,
CharacterSetECI currentCharacterSetECI,
IList<byte[]> byteSegments,
IDictionary<DecodeHintType, object> hints)
{
// Don't crash trying to read more bits than we have available.
if (count << 3 > bits.available())
{
return false;
}
byte[] readBytes = new byte[count];
for (int i = 0; i < count; i++)
{
readBytes[i] = (byte)bits.readBits(8);
}
String encoding;
if (currentCharacterSetECI == null)
{
// The spec isn't clear on this mode; see
// section 6.4.5: t does not say which encoding to assuming
// upon decoding. I have seen ISO-8859-1 used as well as
// Shift_JIS -- without anything like an ECI designator to
// give a hint.
encoding = StringUtils.guessEncoding(readBytes, hints);
}
else
{
encoding = currentCharacterSetECI.EncodingName;
}
try
{
result.Append(Encoding.GetEncoding(encoding).GetString(readBytes, 0, readBytes.Length));
}
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || MONOANDROID || MONOTOUCH)
catch (ArgumentException)
{
try
{
// Silverlight only supports a limited number of character sets, trying fallback to UTF-8
result.Append(Encoding.GetEncoding("UTF-8").GetString(readBytes, 0, readBytes.Length));
}
catch (Exception)
{
return false;
}
}
#endif
#if WindowsCE
catch (PlatformNotSupportedException)
{
try
{
// WindowsCE doesn't support all encodings. But it is device depended.
// So we try here the some different ones
if (encoding == "ISO-8859-1")
{
result.Append(Encoding.GetEncoding(1252).GetString(readBytes, 0, readBytes.Length));
}
else
{
result.Append(Encoding.GetEncoding("UTF-8").GetString(readBytes, 0, readBytes.Length));
}
}
catch (Exception)
{
return false;
}
}
#endif
catch (Exception)
{
return false;
}
byteSegments.Add(readBytes);
return true;
}
private static char toAlphaNumericChar(int value) private static char toAlphaNumericChar(int value)
{ {


+ 12
- 19
shadowsocks-csharp/View/MenuViewController.cs View File

@@ -7,6 +7,7 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using ZXing;
namespace Shadowsocks.View namespace Shadowsocks.View
{ {
@@ -143,6 +144,7 @@ namespace Shadowsocks.View
CreateMenuItem("Update PAC from GFWList", new EventHandler(this.UpdatePACFromGFWListItem_Click)), CreateMenuItem("Update PAC from GFWList", new EventHandler(this.UpdatePACFromGFWListItem_Click)),
new MenuItem("-"), new MenuItem("-"),
CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)), CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)),
CreateMenuItem("Scan QRCode...", new EventHandler(this.ScanQRCodeItem_Click)),
CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)),
CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)), CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)),
new MenuItem("-"), new MenuItem("-"),
@@ -359,41 +361,32 @@ namespace Shadowsocks.View
private void ScanQRCodeItem_Click(object sender, EventArgs e) private void ScanQRCodeItem_Click(object sender, EventArgs e)
{ {
/*
using (Bitmap image = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
using (Bitmap image = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height)) Screen.PrimaryScreen.Bounds.Height))
{ {
using (Graphics g = Graphics.FromImage(bmpScreenCapture))
using (Graphics g = Graphics.FromImage(image))
{ {
g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y, Screen.PrimaryScreen.Bounds.Y,
0, 0, 0, 0,
bmpScreenCapture.Size,
image.Size,
CopyPixelOperation.SourceCopy); CopyPixelOperation.SourceCopy);
} }
resultPoints.Clear();
/* var reader = new BarcodeReader
var reader = new BarcodeReader
{ {
TryHarder = true,
PossibleFormats = new List<BarcodeFormat> PossibleFormats = new List<BarcodeFormat>
{
{
BarcodeFormat.QR_CODE BarcodeFormat.QR_CODE
}
}
}; };
var result = reader.Decode(image); var result = reader.Decode(image);
var result = barcodeReader.Decode(image);
var timerStart = DateTime.Now.Ticks;
var timerStop = DateTime.Now.Ticks;
if (result == null)
if (result != null)
{ {
txtDecoderContent.Text = "No barcode recognized";
Console.WriteLine(result.Text);
} }
labDuration.Text = new TimeSpan(timerStop - timerStart).Milliseconds.ToString("0 ms");
} }
}
* */
} }
private void AutoStartupItem_Click(object sender, EventArgs e) { private void AutoStartupItem_Click(object sender, EventArgs e) {


+ 14
- 0
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -71,6 +71,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="3rd\zxing\BarcodeFormat.cs" /> <Compile Include="3rd\zxing\BarcodeFormat.cs" />
<Compile Include="3rd\zxing\BarcodeReader.cs" />
<Compile Include="3rd\zxing\BarcodeReaderGeneric.cs" />
<Compile Include="3rd\zxing\BaseLuminanceSource.cs" /> <Compile Include="3rd\zxing\BaseLuminanceSource.cs" />
<Compile Include="3rd\zxing\Binarizer.cs" /> <Compile Include="3rd\zxing\Binarizer.cs" />
<Compile Include="3rd\zxing\BinaryBitmap.cs" /> <Compile Include="3rd\zxing\BinaryBitmap.cs" />
@@ -78,22 +80,33 @@
<Compile Include="3rd\zxing\common\BitArray.cs" /> <Compile Include="3rd\zxing\common\BitArray.cs" />
<Compile Include="3rd\zxing\common\BitMatrix.cs" /> <Compile Include="3rd\zxing\common\BitMatrix.cs" />
<Compile Include="3rd\zxing\common\BitSource.cs" /> <Compile Include="3rd\zxing\common\BitSource.cs" />
<Compile Include="3rd\zxing\common\CharacterSetECI.cs" />
<Compile Include="3rd\zxing\common\DecoderResult.cs" /> <Compile Include="3rd\zxing\common\DecoderResult.cs" />
<Compile Include="3rd\zxing\common\DecodingOptions.cs" />
<Compile Include="3rd\zxing\common\DefaultGridSampler.cs" /> <Compile Include="3rd\zxing\common\DefaultGridSampler.cs" />
<Compile Include="3rd\zxing\common\DetectorResult.cs" /> <Compile Include="3rd\zxing\common\DetectorResult.cs" />
<Compile Include="3rd\zxing\common\detector\MathUtils.cs" /> <Compile Include="3rd\zxing\common\detector\MathUtils.cs" />
<Compile Include="3rd\zxing\common\detector\MonochromeRectangleDetector.cs" /> <Compile Include="3rd\zxing\common\detector\MonochromeRectangleDetector.cs" />
<Compile Include="3rd\zxing\common\detector\WhiteRectangleDetector.cs" /> <Compile Include="3rd\zxing\common\detector\WhiteRectangleDetector.cs" />
<Compile Include="3rd\zxing\common\ECI.cs" />
<Compile Include="3rd\zxing\common\EncodingOptions.cs" /> <Compile Include="3rd\zxing\common\EncodingOptions.cs" />
<Compile Include="3rd\zxing\common\GlobalHistogramBinarizer.cs" />
<Compile Include="3rd\zxing\common\GridSampler.cs" /> <Compile Include="3rd\zxing\common\GridSampler.cs" />
<Compile Include="3rd\zxing\common\HybridBinarizer.cs" />
<Compile Include="3rd\zxing\common\PerspectiveTransform.cs" /> <Compile Include="3rd\zxing\common\PerspectiveTransform.cs" />
<Compile Include="3rd\zxing\common\reedsolomon\GenericGF.cs" /> <Compile Include="3rd\zxing\common\reedsolomon\GenericGF.cs" />
<Compile Include="3rd\zxing\common\reedsolomon\GenericGFPoly.cs" /> <Compile Include="3rd\zxing\common\reedsolomon\GenericGFPoly.cs" />
<Compile Include="3rd\zxing\common\reedsolomon\ReedSolomonDecoder.cs" /> <Compile Include="3rd\zxing\common\reedsolomon\ReedSolomonDecoder.cs" />
<Compile Include="3rd\zxing\common\reedsolomon\ReedSolomonEncoder.cs" /> <Compile Include="3rd\zxing\common\reedsolomon\ReedSolomonEncoder.cs" />
<Compile Include="3rd\zxing\common\StringUtils.cs" />
<Compile Include="3rd\zxing\DecodeHintType.cs" /> <Compile Include="3rd\zxing\DecodeHintType.cs" />
<Compile Include="3rd\zxing\EncodeHintType.cs" /> <Compile Include="3rd\zxing\EncodeHintType.cs" />
<Compile Include="3rd\zxing\IBarcodeReader.cs" />
<Compile Include="3rd\zxing\IBarcodeReaderGeneric.cs" />
<Compile Include="3rd\zxing\LuminanceSource.cs" /> <Compile Include="3rd\zxing\LuminanceSource.cs" />
<Compile Include="3rd\zxing\net2.0\Action.cs" />
<Compile Include="3rd\zxing\net2.0\Func.cs" />
<Compile Include="3rd\zxing\net2.0\TimeZoneInfo.cs" />
<Compile Include="3rd\zxing\qrcode\decoder\BitMatrixParser.cs" /> <Compile Include="3rd\zxing\qrcode\decoder\BitMatrixParser.cs" />
<Compile Include="3rd\zxing\qrcode\decoder\DataBlock.cs" /> <Compile Include="3rd\zxing\qrcode\decoder\DataBlock.cs" />
<Compile Include="3rd\zxing\qrcode\decoder\DataMask.cs" /> <Compile Include="3rd\zxing\qrcode\decoder\DataMask.cs" />
@@ -125,6 +138,7 @@
<Compile Include="3rd\zxing\ResultMetadataType.cs" /> <Compile Include="3rd\zxing\ResultMetadataType.cs" />
<Compile Include="3rd\zxing\ResultPoint.cs" /> <Compile Include="3rd\zxing\ResultPoint.cs" />
<Compile Include="3rd\zxing\ResultPointCallback.cs" /> <Compile Include="3rd\zxing\ResultPointCallback.cs" />
<Compile Include="3rd\zxing\RGBLuminanceSource.cs" />
<Compile Include="3rd\zxing\WriterException.cs" /> <Compile Include="3rd\zxing\WriterException.cs" />
<Compile Include="Controller\AutoStartup.cs" /> <Compile Include="Controller\AutoStartup.cs" />
<Compile Include="Controller\FileManager.cs" /> <Compile Include="Controller\FileManager.cs" />


Loading…
Cancel
Save