libdmtx 0.7.8.7
libdmtx is a software library that enables programs to read and write Data Matrix barcodes of the modern ECC200 variety.
Loading...
Searching...
No Matches
dmtxencodeedifact.c
Go to the documentation of this file.
1
17#include "dmtx.h"
18#include "dmtxstatic.h"
19
25{
26 DmtxByte value;
27
28 if (streamInputHasNext(stream)) {
29 /* Check for FNC1 character, which needs to be sent in ASCII */
30 value = streamInputPeekNext(stream);
31 CHKERR;
32
33 if ((value < 32 || value > 94)) {
35 return;
36 }
37
38 if (stream->fnc1 != DmtxUndefined && (int)value == stream->fnc1) {
40 CHKERR;
41
43 CHKERR;
45 CHKERR;
46 return;
47 }
48
49 value = streamInputAdvanceNext(stream);
50 CHKERR;
51 appendValueEdifact(stream, value);
52 CHKERR;
53 }
54}
55
60static void appendValueEdifact(DmtxEncodeStream *stream, DmtxByte value)
61{
62 DmtxByte edifactValue, previousOutput;
63
65
66 /*
67 * TODO: KECA -> korean, circles
68 * TODO: UNOX -> ISO-2022-JP
69 * TODO: and so on
70 */
71 if (value < 31 || value > 94) {
73 return;
74 }
75
76 edifactValue = (value & 0x3f) << 2;
77
78 switch (stream->outputChainValueCount % 4) {
79 case 0:
80 streamOutputChainAppend(stream, edifactValue);
81 CHKERR;
82 break;
83 case 1:
84 previousOutput = streamOutputChainRemoveLast(stream);
85 CHKERR;
86 streamOutputChainAppend(stream, previousOutput | (edifactValue >> 6));
87 CHKERR;
88 streamOutputChainAppend(stream, edifactValue << 2);
89 CHKERR;
90 break;
91 case 2:
92 previousOutput = streamOutputChainRemoveLast(stream);
93 CHKERR;
94 streamOutputChainAppend(stream, previousOutput | (edifactValue >> 4));
95 CHKERR;
96 streamOutputChainAppend(stream, edifactValue << 4);
97 CHKERR;
98 break;
99 case 3:
100 previousOutput = streamOutputChainRemoveLast(stream);
101 CHKERR;
102 streamOutputChainAppend(stream, previousOutput | (edifactValue >> 2));
103 CHKERR;
104 break;
105 }
106
107 stream->outputChainValueCount++;
108}
109
126static void completeIfDoneEdifact(DmtxEncodeStream *stream, int sizeIdxRequest)
127{
128 int i;
129 int sizeIdx;
130 int symbolRemaining;
131 DmtxBoolean cleanBoundary;
132 DmtxPassFail passFail;
133 DmtxByte outputTmpStorage[3];
134 DmtxByteList outputTmp;
135
136 if (stream->status == DmtxStatusComplete) {
137 return;
138 }
139
140 /*
141 * If we just completed a triplet (cleanBoundary), 1 or 2 symbol codewords
142 * remain, and our remaining inputs (if any) represented in ASCII would fit
143 * in the remaining space, encode them in ASCII with an implicit unlatch.
144 */
145
146 cleanBoundary = (stream->outputChainValueCount % 4 == 0) ? DmtxTrue : DmtxFalse;
147
148 if (cleanBoundary == DmtxTrue) {
149 /* Encode up to 3 codewords to a temporary stream */
150 outputTmp = encodeTmpRemainingInAscii(stream, outputTmpStorage, sizeof(outputTmpStorage), &passFail);
151
152 if (passFail == DmtxFail) {
154 return;
155 }
156
157 if (outputTmp.length < 3) {
158 /* Find minimum symbol size for projected length */
159 sizeIdx = findSymbolSize(stream->output->length + outputTmp.length, sizeIdxRequest);
160 CHKSIZE;
161
162 /* Find remaining capacity over current length */
163 symbolRemaining = getRemainingSymbolCapacity(stream->output->length, sizeIdx);
164 CHKERR;
165
166 if (symbolRemaining < 3 && outputTmp.length <= symbolRemaining) {
168 CHKERR;
169
170 for (i = 0; i < outputTmp.length; i++) {
171 appendValueAscii(stream, outputTmp.b[i]);
172 CHKERR;
173 }
174
175 /* Register progress since encoding happened outside normal path */
176 stream->inputNext = stream->input->length;
177
178 /* Pad remaining if necessary */
179 padRemainingInAscii(stream, sizeIdx);
180 CHKERR;
181 streamMarkComplete(stream, sizeIdx);
182 return;
183 }
184 }
185 }
186
187 if (!streamInputHasNext(stream)) {
188 sizeIdx = findSymbolSize(stream->output->length, sizeIdxRequest);
189 CHKSIZE;
190 symbolRemaining = getRemainingSymbolCapacity(stream->output->length, sizeIdx);
191 CHKERR;
192
193 /* Explicit unlatch required unless on clean boundary and full symbol */
194 if (cleanBoundary == DmtxFalse || symbolRemaining > 0) {
196 CHKERR;
197 sizeIdx = findSymbolSize(stream->output->length, sizeIdxRequest);
198 CHKSIZE;
199 padRemainingInAscii(stream, sizeIdx);
200 CHKERR;
201 }
202
203 streamMarkComplete(stream, sizeIdx);
204 }
205}
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
#define DmtxPassFail
Definition dmtx.h:42
#define DmtxTrue
Definition dmtx.h:47
#define DmtxBoolean
Definition dmtx.h:46
#define DmtxUndefined
Definition dmtx.h:40
@ DmtxSchemeEdifact
Definition dmtx.h:94
@ DmtxSchemeAscii
Definition dmtx.h:90
#define DmtxFalse
Definition dmtx.h:48
unsigned char DmtxByte
Definition dmtx.h:293
#define DmtxFail
Definition dmtx.h:44
@ DmtxStatusComplete
Definition dmtx.h:81
static void completeIfDoneEdifact(DmtxEncodeStream *stream, int sizeIdxRequest)
Complete EDIFACT encoding if it matches a known end-of-symbol condition.
static void encodeNextChunkEdifact(DmtxEncodeStream *stream)
static void appendValueEdifact(DmtxEncodeStream *stream, DmtxByte value)
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
static DmtxByte streamInputAdvanceNext(DmtxEncodeStream *stream)
#define CHKSIZE
Definition dmtxstatic.h:88
#define CHKSCHEME(s)
Definition dmtxstatic.h:71
static void streamOutputChainAppend(DmtxEncodeStream *stream, DmtxByte value)
#define DmtxChannelUnsupportedChar
Definition dmtxstatic.h:58
@ DmtxErrorUnknown
Definition dmtxstatic.h:394
static void padRemainingInAscii(DmtxEncodeStream *stream, int sizeIdx)
static void streamMarkInvalid(DmtxEncodeStream *stream, int reasonIdx)
static DmtxByte streamInputPeekNext(DmtxEncodeStream *stream)
static DmtxByte streamOutputChainRemoveLast(DmtxEncodeStream *stream)
static int findSymbolSize(int dataWords, int sizeIdxRequest)
static DmtxByteList encodeTmpRemainingInAscii(DmtxEncodeStream *stream, DmtxByte *storage, int capacity, DmtxPassFail *passFail)
static void streamMarkComplete(DmtxEncodeStream *stream, int sizeIdx)
#define DmtxUnlatchImplicit
Definition dmtxstatic.h:55
static void encodeChangeScheme(DmtxEncodeStream *stream, DmtxScheme targetScheme, int unlatchType)
static int getRemainingSymbolCapacity(int outputLength, int sizeIdx)
static void appendValueAscii(DmtxEncodeStream *stream, DmtxByte value)
#define DmtxUnlatchExplicit
Definition dmtxstatic.h:54
#define DmtxValueFNC1
Definition dmtxstatic.h:42
#define CHKERR
Definition dmtxstatic.h:80
static void streamMarkFatal(DmtxEncodeStream *stream, int reasonIdx)
static DmtxBoolean streamInputHasNext(DmtxEncodeStream *stream)
DmtxByteList Use signed int for length fields instead of size_t to play nicely with RS arithmetic.
DmtxByteList * input
Definition dmtx.h:318
DmtxByteList * output
Definition dmtx.h:319
DmtxStatus status
Definition dmtx.h:317