You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
8.5 KiB
270 lines
8.5 KiB
/*
|
|
DataMatrix.Net
|
|
|
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
|
Copyright (C) 2009/2010 Michael Faschinger
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 3.0 of the License, or (at your option) any later version.
|
|
You can also redistribute and/or modify it under the terms of the
|
|
GNU Lesser General Public License as published by the Free Software
|
|
Foundation; either version 3.0 of the License or (at your option)
|
|
any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License or the GNU Lesser General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public
|
|
License and the GNU Lesser General Public License along with this
|
|
library; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
Contact: Michael Faschinger - michfasch@gmx.at
|
|
|
|
*/
|
|
|
|
using System;
|
|
|
|
namespace DataMatrix.net
|
|
{
|
|
internal class DmtxImage
|
|
{
|
|
#region Fields
|
|
|
|
int _rowPadBytes;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
internal DmtxImage(byte[] pxl, int width, int height, DmtxPackOrder pack)
|
|
{
|
|
this.BitsPerChannel = new int[4];
|
|
this.ChannelStart = new int[4];
|
|
if (pxl == null || width < 1 || height < 1)
|
|
{
|
|
throw new ArgumentException("Cannot create image of size null");
|
|
}
|
|
|
|
this.Pxl = pxl;
|
|
this.Width = width;
|
|
this.Height = height;
|
|
this.PixelPacking = pack;
|
|
this.BitsPerPixel = DmtxCommon.GetBitsPerPixel(pack);
|
|
this.BytesPerPixel = this.BitsPerPixel / 8;
|
|
this._rowPadBytes = 0;
|
|
this.RowSizeBytes = this.Width * this.BytesPerPixel + this._rowPadBytes;
|
|
this.ImageFlip = DmtxFlip.DmtxFlipNone;
|
|
|
|
/* Leave channelStart[] and bitsPerChannel[] with zeros from calloc */
|
|
this.ChannelCount = 0;
|
|
|
|
switch (pack)
|
|
{
|
|
case DmtxPackOrder.DmtxPackCustom:
|
|
break;
|
|
case DmtxPackOrder.DmtxPack1bppK:
|
|
throw new ArgumentException("Cannot create image: not supported pack order!");
|
|
case DmtxPackOrder.DmtxPack8bppK:
|
|
SetChannel(0, 8);
|
|
break;
|
|
case DmtxPackOrder.DmtxPack16bppRGB:
|
|
case DmtxPackOrder.DmtxPack16bppBGR:
|
|
case DmtxPackOrder.DmtxPack16bppYCbCr:
|
|
SetChannel(0, 5);
|
|
SetChannel(5, 5);
|
|
SetChannel(10, 5);
|
|
break;
|
|
case DmtxPackOrder.DmtxPack24bppRGB:
|
|
case DmtxPackOrder.DmtxPack24bppBGR:
|
|
case DmtxPackOrder.DmtxPack24bppYCbCr:
|
|
case DmtxPackOrder.DmtxPack32bppRGBX:
|
|
case DmtxPackOrder.DmtxPack32bppBGRX:
|
|
SetChannel(0, 8);
|
|
SetChannel(8, 8);
|
|
SetChannel(16, 8);
|
|
break;
|
|
case DmtxPackOrder.DmtxPack16bppRGBX:
|
|
case DmtxPackOrder.DmtxPack16bppBGRX:
|
|
SetChannel(0, 5);
|
|
SetChannel(5, 5);
|
|
SetChannel(10, 5);
|
|
break;
|
|
case DmtxPackOrder.DmtxPack16bppXRGB:
|
|
case DmtxPackOrder.DmtxPack16bppXBGR:
|
|
SetChannel(1, 5);
|
|
SetChannel(6, 5);
|
|
SetChannel(11, 5);
|
|
break;
|
|
case DmtxPackOrder.DmtxPack32bppXRGB:
|
|
case DmtxPackOrder.DmtxPack32bppXBGR:
|
|
SetChannel(8, 8);
|
|
SetChannel(16, 8);
|
|
SetChannel(24, 8);
|
|
break;
|
|
case DmtxPackOrder.DmtxPack32bppCMYK:
|
|
SetChannel(0, 8);
|
|
SetChannel(8, 8);
|
|
SetChannel(16, 8);
|
|
SetChannel(24, 8);
|
|
break;
|
|
default:
|
|
throw new ArgumentException("Cannot create image: Invalid Pack Order");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Methods
|
|
internal bool SetChannel(int channelStart, int bitsPerChannel)
|
|
{
|
|
if (this.ChannelCount >= 4) /* IMAGE_MAX_CHANNEL */
|
|
return false;
|
|
|
|
/* New channel extends beyond pixel data */
|
|
|
|
this.BitsPerChannel[this.ChannelCount] = bitsPerChannel;
|
|
this.ChannelStart[this.ChannelCount] = channelStart;
|
|
(this.ChannelCount)++;
|
|
|
|
return true;
|
|
}
|
|
|
|
internal int GetByteOffset(int x, int y)
|
|
{
|
|
if (this.ImageFlip == DmtxFlip.DmtxFlipX)
|
|
{
|
|
throw new ArgumentException("DmtxFlipX is not an option!");
|
|
}
|
|
|
|
if (!ContainsInt(0, x, y))
|
|
return DmtxConstants.DmtxUndefined;
|
|
|
|
if (this.ImageFlip == DmtxFlip.DmtxFlipY)
|
|
return (y * this.RowSizeBytes + x * this.BytesPerPixel);
|
|
|
|
return ((this.Height - y - 1) * this.RowSizeBytes + x * this.BytesPerPixel);
|
|
}
|
|
|
|
internal bool GetPixelValue(int x, int y, int channel, ref int value)
|
|
{
|
|
if (channel >= this.ChannelCount)
|
|
{
|
|
throw new ArgumentException("Channel greater than channel count!");
|
|
}
|
|
|
|
int offset = GetByteOffset(x, y);
|
|
if (offset == DmtxConstants.DmtxUndefined)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
switch (this.BitsPerChannel[channel])
|
|
{
|
|
case 1:
|
|
break;
|
|
case 5:
|
|
break;
|
|
case 8:
|
|
if (this.ChannelStart[channel] % 8 != 0 || this.BitsPerPixel % 8 != 0)
|
|
{
|
|
throw new Exception("Error getting pixel value");
|
|
}
|
|
value = this.Pxl[offset + channel];
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
internal bool SetPixelValue(int x, int y, int channel, byte value)
|
|
{
|
|
if (channel >= this.ChannelCount)
|
|
{
|
|
throw new ArgumentException("Channel greater than channel count!");
|
|
}
|
|
|
|
int offset = GetByteOffset(x, y);
|
|
if (offset == DmtxConstants.DmtxUndefined)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
switch (this.BitsPerChannel[channel])
|
|
{
|
|
case 1:
|
|
break;
|
|
case 5:
|
|
break;
|
|
case 8:
|
|
if (this.ChannelStart[channel] % 8 != 0 || this.BitsPerPixel % 8 != 0)
|
|
{
|
|
throw new Exception("Error getting pixel value");
|
|
}
|
|
this.Pxl[offset + channel] = value;
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
internal bool ContainsInt(int margin, int x, int y)
|
|
{
|
|
if (x - margin >= 0 && x + margin < this.Width &&
|
|
y - margin >= 0 && y + margin < this.Height)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
internal bool ContainsFloat(double x, double y)
|
|
{
|
|
if (x >= 0.0 && x < this.Width && y >= 0.0 && y < this.Height)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
internal int Width { get; set; }
|
|
|
|
internal int Height { get; set; }
|
|
|
|
internal DmtxPackOrder PixelPacking { get; set; }
|
|
|
|
internal int BitsPerPixel { get; set; }
|
|
|
|
internal int BytesPerPixel { get; set; }
|
|
|
|
internal int RowPadBytes
|
|
{
|
|
get { return _rowPadBytes; }
|
|
set
|
|
{
|
|
_rowPadBytes = value;
|
|
this.RowSizeBytes = this.Width * (this.BitsPerPixel / 8) + this._rowPadBytes;
|
|
}
|
|
}
|
|
|
|
internal int RowSizeBytes { get; set; }
|
|
|
|
internal DmtxFlip ImageFlip { get; set; }
|
|
|
|
internal int ChannelCount { get; set; }
|
|
|
|
internal int[] ChannelStart { get; set; }
|
|
|
|
internal int[] BitsPerChannel { get; set; }
|
|
|
|
internal byte[] Pxl { get; set; }
|
|
|
|
#endregion
|
|
}
|
|
}
|