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
dmtxencodescheme.c
Go to the documentation of this file.
1
17#include <assert.h>
18
19#include "dmtx.h"
20#include "dmtxstatic.h"
21
73/* Verify stream is using expected scheme */
74#define CHKSCHEME(s) \
75 { \
76 if (stream->currentScheme != (s)) { \
77 streamMarkFatal(stream, DmtxErrorUnexpectedScheme); \
78 return; \
79 } \
80 }
81
82/* CHKERR should follow any call that might alter stream status */
83#define CHKERR \
84 { \
85 if (stream->status != DmtxStatusEncoding) { \
86 return; \
87 } \
88 }
89
90/* CHKSIZE should follows typical calls to findSymbolSize() */
91#define CHKSIZE \
92 { \
93 if (sizeIdx == DmtxUndefined) { \
94 streamMarkInvalid(stream, DmtxErrorUnknown); \
95 return; \
96 } \
97 }
98
103static int encodeSingleScheme(DmtxByteList *input, DmtxByteList *output, int sizeIdxRequest, DmtxScheme scheme,
104 int fnc1)
105{
106 DmtxEncodeStream stream;
107
108 stream = streamInit(input, output);
109 stream.fnc1 = fnc1;
110
111 /* 1st FNC1 special case, encode before scheme switch */
112 if (fnc1 != DmtxUndefined && (int)(input->b[0]) == fnc1) {
113 streamInputAdvanceNext(&stream);
115 }
116
117 /* Continue encoding until complete */
118 while (stream.status == DmtxStatusEncoding) {
119 encodeNextChunk(&stream, scheme, DmtxEncodeNormal, sizeIdxRequest);
120 }
121
122 /* Verify encoding completed and all inputs were consumed */
123 if (stream.status != DmtxStatusComplete || streamInputHasNext(&stream)) {
124 return DmtxUndefined;
125 }
126
127 return stream.sizeIdx;
128}
129
137static void encodeNextChunk(DmtxEncodeStream *stream, int scheme, int option, int sizeIdxRequest)
138{
139 /* Special case: Prevent X12 from entering state with no way to unlatch */
140 if (stream->currentScheme != DmtxSchemeX12 && scheme == DmtxSchemeX12) {
141 if (partialX12ChunkRemains(stream)) {
142 scheme = DmtxSchemeAscii;
143 }
144 }
145
146 /* Change to target scheme if necessary */
147 if (stream->currentScheme != scheme) {
149 CHKERR;
150 CHKSCHEME(scheme);
151 }
152
153 /* Special case: Edifact may be done before writing first word */
154 if (scheme == DmtxSchemeEdifact) {
155 completeIfDoneEdifact(stream, sizeIdxRequest);
156 }
157 CHKERR;
158
159 switch (stream->currentScheme) {
160 case DmtxSchemeAscii:
161 encodeNextChunkAscii(stream, option);
162 CHKERR;
163 completeIfDoneAscii(stream, sizeIdxRequest);
164 CHKERR;
165 break;
166 case DmtxSchemeC40:
167 case DmtxSchemeText:
168 case DmtxSchemeX12:
169 encodeNextChunkCTX(stream, sizeIdxRequest);
170 CHKERR;
171 completeIfDoneCTX(stream, sizeIdxRequest);
172 CHKERR;
173 break;
176 CHKERR;
177 completeIfDoneEdifact(stream, sizeIdxRequest);
178 CHKERR;
179 break;
182 CHKERR;
183 completeIfDoneBase256(stream, sizeIdxRequest);
184 CHKERR;
185 break;
186 default:
188 break;
189 }
190}
191
196static void encodeChangeScheme(DmtxEncodeStream *stream, DmtxScheme targetScheme, int unlatchType)
197{
198 /* Nothing to do */
199 if (stream->currentScheme == targetScheme) {
200 return;
201 }
202
203 /* Every latch must go through ASCII */
204 switch (stream->currentScheme) {
205 case DmtxSchemeC40:
206 case DmtxSchemeText:
207 case DmtxSchemeX12:
208 if (unlatchType == DmtxUnlatchExplicit) {
209 appendUnlatchCTX(stream);
210 CHKERR;
211 }
212 break;
214 if (unlatchType == DmtxUnlatchExplicit) {
216 CHKERR;
217 }
218 break;
219 default:
220 /* Nothing to do for ASCII or Base 256 */
222 break;
223 }
225
226 /* Anything other than ASCII (the default) requires a latch */
227 switch (targetScheme) {
228 case DmtxSchemeC40:
230 CHKERR;
231 break;
232 case DmtxSchemeText:
234 CHKERR;
235 break;
236 case DmtxSchemeX12:
238 CHKERR;
239 break;
242 CHKERR;
243 break;
246 CHKERR;
247 break;
248 default:
249 /* Nothing to do for ASCII */
251 break;
252 }
253 stream->currentScheme = targetScheme;
254
255 /* Reset new chain length to zero */
256 stream->outputChainWordCount = 0;
257 stream->outputChainValueCount = 0;
258
259 /* Insert header byte if just latched to Base256 */
260 if (targetScheme == DmtxSchemeBase256) {
262 CHKERR;
263 }
264}
265
270static int getRemainingSymbolCapacity(int outputLength, int sizeIdx)
271{
272 int capacity;
273 int remaining;
274
275 if (sizeIdx == DmtxUndefined) {
276 remaining = DmtxUndefined;
277 } else {
279 remaining = capacity - outputLength;
280 }
281
282 return remaining;
283}
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
int dmtxGetSymbolAttribute(int attribute, int sizeIdx)
根据规格索引返回二维码规格各个参数
Definition dmtxsymbol.c:45
@ DmtxSymAttribSymbolDataWords
Definition dmtx.h:165
enum DmtxScheme_enum DmtxScheme
#define DmtxUndefined
Definition dmtx.h:40
@ DmtxSchemeText
Definition dmtx.h:92
@ DmtxSchemeC40
Definition dmtx.h:91
@ DmtxSchemeBase256
Definition dmtx.h:95
@ DmtxSchemeEdifact
Definition dmtx.h:94
@ DmtxSchemeX12
Definition dmtx.h:93
@ DmtxSchemeAscii
Definition dmtx.h:90
@ DmtxStatusComplete
Definition dmtx.h:81
@ DmtxStatusEncoding
Definition dmtx.h:80
static int encodeSingleScheme(DmtxByteList *input, DmtxByteList *output, int sizeIdxRequest, DmtxScheme scheme, int fnc1)
#define CHKSCHEME(s)
In this file:
static void encodeNextChunk(DmtxEncodeStream *stream, int scheme, int option, int sizeIdxRequest)
This function distributes work to the equivalent scheme-specific implementation.
static void encodeChangeScheme(DmtxEncodeStream *stream, DmtxScheme targetScheme, int unlatchType)
static int getRemainingSymbolCapacity(int outputLength, int sizeIdx)
#define CHKERR
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
static DmtxByte streamInputAdvanceNext(DmtxEncodeStream *stream)
static void completeIfDoneAscii(DmtxEncodeStream *stream, int sizeIdxRequest)
static void encodeNextChunkBase256(DmtxEncodeStream *stream)
#define DmtxValueBase256Latch
Definition dmtxstatic.h:32
static void updateBase256ChainHeader(DmtxEncodeStream *stream, int perfectSizeIdx)
@ DmtxEncodeNormal
Definition dmtxstatic.h:107
static void completeIfDoneCTX(DmtxEncodeStream *stream, int sizeIdxRequest)
@ DmtxErrorUnknown
Definition dmtxstatic.h:394
static void completeIfDoneEdifact(DmtxEncodeStream *stream, int sizeIdxRequest)
static DmtxEncodeStream streamInit(DmtxByteList *input, DmtxByteList *output)
static void appendUnlatchCTX(DmtxEncodeStream *stream)
#define DmtxValueC40Latch
Definition dmtxstatic.h:28
#define DmtxAssert(expr)
Definition dmtxstatic.h:96
static void encodeNextChunkAscii(DmtxEncodeStream *stream, int option)
static DmtxBoolean partialX12ChunkRemains(DmtxEncodeStream *stream)
static void encodeNextChunkCTX(DmtxEncodeStream *stream, int sizeIdxRequest)
static void completeIfDoneBase256(DmtxEncodeStream *stream, int sizeIdxRequest)
#define DmtxValueTextLatch
Definition dmtxstatic.h:29
static void encodeNextChunkEdifact(DmtxEncodeStream *stream)
static void appendValueAscii(DmtxEncodeStream *stream, DmtxByte value)
#define DmtxUnlatchExplicit
Definition dmtxstatic.h:54
#define DmtxValueX12Latch
Definition dmtxstatic.h:30
#define DmtxValueFNC1
Definition dmtxstatic.h:42
static void streamMarkFatal(DmtxEncodeStream *stream, int reasonIdx)
#define DmtxValueEdifactUnlatch
Definition dmtxstatic.h:35
static void appendValueEdifact(DmtxEncodeStream *stream, DmtxByte value)
static DmtxBoolean streamInputHasNext(DmtxEncodeStream *stream)
#define DmtxValueEdifactLatch
Definition dmtxstatic.h:31
DmtxByteList Use signed int for length fields instead of size_t to play nicely with RS arithmetic.
DmtxStatus status
Definition dmtx.h:317