![]() ![]() | ![]() |
1.1 misho 1: /*
2: * "streamable kanji code filter and converter"
3: * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
4: *
5: * LICENSE NOTICES
6: *
7: * This file is part of "streamable kanji code filter and converter",
8: * which is distributed under the terms of GNU Lesser General Public
9: * License (version 2) as published by the Free Software Foundation.
10: *
11: * This software is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU Lesser General Public License for more details.
15: *
16: * You should have received a copy of the GNU Lesser General Public
17: * License along with "streamable kanji code filter and converter";
18: * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19: * Suite 330, Boston, MA 02111-1307 USA
20: *
21: * The author of this file:
22: *
23: */
24: /*
25: * The source code included in this files was separated from mbfilter_sjis.c
26: * by rui hirokawa <hirokawa@php.net> on 15 aug 2011.
27: *
28: */
29:
30: #ifdef HAVE_CONFIG_H
31: #include "config.h"
32: #endif
33:
34: #include "mbfilter.h"
35: #include "mbfilter_sjis_2004.h"
36:
37: #include "unicode_table_jis2004.h"
38: #include "unicode_table_jis.h"
39:
40: extern const unsigned char mblen_table_sjis[];
41:
42: static int mbfl_filt_ident_sjis2004(int c, mbfl_identify_filter *filter);
43:
44: extern int mbfl_filt_ident_sjis(int c, mbfl_identify_filter *filter);
45: extern int mbfl_bisec_srch(int w, const unsigned short *tbl, int n);
46: extern int mbfl_bisec_srch2(int w, const unsigned short tbl[], int n);
47:
48: static const char *mbfl_encoding_sjis2004_aliases[] = {"SJIS2004","Shift_JIS-2004", NULL};
49:
50: const mbfl_encoding mbfl_encoding_sjis2004 = {
51: mbfl_no_encoding_sjis2004,
52: "SJIS-2004",
53: "Shift_JIS",
54: (const char *(*)[])&mbfl_encoding_sjis2004_aliases,
55: mblen_table_sjis,
56: MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
57: };
58:
59: const struct mbfl_identify_vtbl vtbl_identify_sjis2004 = {
60: mbfl_no_encoding_sjis2004,
61: mbfl_filt_ident_common_ctor,
62: mbfl_filt_ident_common_dtor,
63: mbfl_filt_ident_sjis
64: };
65:
66: const struct mbfl_convert_vtbl vtbl_sjis2004_wchar = {
67: mbfl_no_encoding_sjis2004,
68: mbfl_no_encoding_wchar,
69: mbfl_filt_conv_common_ctor,
70: mbfl_filt_conv_common_dtor,
71: mbfl_filt_conv_jis2004_wchar,
72: mbfl_filt_conv_common_flush
73: };
74:
75: const struct mbfl_convert_vtbl vtbl_wchar_sjis2004 = {
76: mbfl_no_encoding_wchar,
77: mbfl_no_encoding_sjis2004,
78: mbfl_filt_conv_common_ctor,
79: mbfl_filt_conv_common_dtor,
80: mbfl_filt_conv_wchar_jis2004,
81: mbfl_filt_conv_jis2004_flush
82: };
83:
84: #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
85:
86: #define SJIS_ENCODE(c1,c2,s1,s2) \
87: do { \
88: s1 = c1; \
89: s1--; \
90: s1 >>= 1; \
91: if ((c1) < 0x5f) { \
92: s1 += 0x71; \
93: } else { \
94: s1 += 0xb1; \
95: } \
96: s2 = c2; \
97: if ((c1) & 1) { \
98: if ((c2) < 0x60) { \
99: s2--; \
100: } \
101: s2 += 0x20; \
102: } else { \
103: s2 += 0x7e; \
104: } \
105: } while (0)
106:
107: #define SJIS_DECODE(c1,c2,s1,s2) \
108: do { \
109: s1 = c1; \
110: if (s1 < 0xa0) { \
111: s1 -= 0x81; \
112: } else { \
113: s1 -= 0xc1; \
114: } \
115: s1 <<= 1; \
116: s1 += 0x21; \
117: s2 = c2; \
118: if (s2 < 0x9f) { \
119: if (s2 < 0x7f) { \
120: s2++; \
121: } \
122: s2 -= 0x20; \
123: } else { \
124: s1++; \
125: s2 -= 0x7e; \
126: } \
127: } while (0)
128:
129:
130: /*
131: * JIS-2004 => wchar
132: */
133: int
134: mbfl_filt_conv_jis2004_wchar(int c, mbfl_convert_filter *filter)
135: {
136: int k;
1.1.1.2 ! misho 137: int c1, c2, s, s1 = 0, s2 = 0, w = 0, w1;
1.1 misho 138:
139: retry:
140: switch (filter->status & 0xf) {
141: case 0:
142: if (c >= 0 && c < 0x80) { /* latin */
143: if (filter->from->no_encoding == mbfl_no_encoding_eucjp2004) {
144: CK((*filter->output_function)(c, filter->data));
145: } else if (filter->from->no_encoding == mbfl_no_encoding_sjis2004) {
146: if (c == 0x5c) {
147: CK((*filter->output_function)(0x00a5, filter->data));
148: } else if (c == 0x7e) {
149: CK((*filter->output_function)(0x203e, filter->data));
150: } else {
151: CK((*filter->output_function)(c, filter->data));
152: }
153: } else { /* ISO-2022-JP-2004 */
154: if (c == 0x1b) {
155: filter->status += 6;
156: } else if ((filter->status == 0x80 || filter->status == 0x90 || filter->status == 0xa0)
157: && c > 0x20 && c < 0x7f) { /* kanji first char */
158: filter->cache = c;
159: if (filter->status == 0x90) {
160: filter->status += 1; /* JIS X 0213 plane 1 */
161: } else if (filter->status == 0xa0) {
162: filter->status += 4; /* JIS X 0213 plane 2 */
163: } else {
164: filter->status += 5; /* JIS X 0208 */
165: }
166: } else {
167: CK((*filter->output_function)(c, filter->data));
168: }
169: }
170: } else {
171: if (filter->from->no_encoding == mbfl_no_encoding_eucjp2004) {
172: if (c > 0xa0 && c < 0xff) { /* X 0213 plane 1 first char */
173: filter->status = 1;
174: filter->cache = c;
175: } else if (c == 0x8e) { /* kana first char */
176: filter->status = 2;
177: } else if (c == 0x8f) { /* X 0213 plane 2 first char */
178: filter->status = 3;
179: } else {
180: w = c & MBFL_WCSGROUP_MASK;
181: w |= MBFL_WCSGROUP_THROUGH;
182: CK((*filter->output_function)(w, filter->data));
183: }
184: } else if (filter->from->no_encoding == mbfl_no_encoding_sjis2004) {
185: if (c > 0xa0 && c < 0xe0) { /* kana */
186: CK((*filter->output_function)(0xfec0 + c, filter->data));
187: } else if (c > 0x80 && c < 0xfd && c != 0xa0) { /* kanji first char */
188: filter->status = 1;
189: filter->cache = c;
190: } else {
191: w = c & MBFL_WCSGROUP_MASK;
192: w |= MBFL_WCSGROUP_THROUGH;
193: CK((*filter->output_function)(w, filter->data));
194: }
195: } else {
196: w = c & MBFL_WCSGROUP_MASK;
197: w |= MBFL_WCSGROUP_THROUGH;
198: CK((*filter->output_function)(w, filter->data));
199: }
200: }
201: break;
202:
203: case 1: /* kanji second char */
204: filter->status &= ~0xf;
205: c1 = filter->cache;
206:
207: if (filter->from->no_encoding == mbfl_no_encoding_eucjp2004) {
208: if (c > 0xa0 && c < 0xff) {
209: s1 = c1 - 0x80;
210: s2 = c - 0x80;
211: }
212: } else if (filter->from->no_encoding == mbfl_no_encoding_sjis2004) {
213: if (c >= 0x40 && c <= 0xfc && c != 0x7f) {
214: SJIS_DECODE(c1, c, s1, s2);
215: }
216: } else {
217: s1 = c1;
218: s2 = c;
219: }
220: w1 = (s1 << 8) | s2;
221:
222: if (w1 >= 0x2121) {
223: /* conversion for combining characters */
224: if ((w1 >= 0x2477 && w1 <= 0x2479) || (w1 >= 0x2479 && w1 <= 0x247B) ||
225: (w1 >= 0x2577 && w1 <= 0x257E) || w1 == 0x2678 || w1 == 0x2B44 ||
226: (w1 >= 0x2B48 && w1 <= 0x2B4F) || (w1 >= 0x2B65 && w1 <= 0x2B66)) {
227: k = mbfl_bisec_srch2(w1, jisx0213_u2_key, jisx0213_u2_tbl_len);
228: if (k >= 0) {
229: w = jisx0213_u2_tbl[2*k];
230: CK((*filter->output_function)(w, filter->data));
231: w = jisx0213_u2_tbl[2*k+1];
232: }
233: }
234:
235: /* conversion for BMP */
236: if (w <= 0) {
237: w1 = (s1 - 0x21)*94 + s2 - 0x21;
238: if (w1 >= 0 && w1 < jisx0213_ucs_table_size) {
239: w = jisx0213_ucs_table[w1];
240: }
241: }
242:
243: /* conversion for CJK Unified Ideographs ext.B (U+2XXXX) */
244: if (w <= 0) {
245: w1 = (s1 << 8) | s2;
246: k = mbfl_bisec_srch2(w1, jisx0213_jis_u5_key, jisx0213_u5_tbl_len);
247: if (k >= 0) {
248: w = jisx0213_jis_u5_tbl[k] + 0x20000;
249: }
250: }
251:
252: if (w <= 0) {
253: if (s1 < 0x7f && s2 < 0x7f) {
254: w = (s1 << 8) | s2;
255: w &= MBFL_WCSPLANE_MASK;
256: w |= MBFL_WCSPLANE_JIS0213;
257: } else {
258: w = (c1 << 8) | c;
259: w &= MBFL_WCSGROUP_MASK;
260: w |= MBFL_WCSGROUP_THROUGH;
261: }
262: }
263: CK((*filter->output_function)(w, filter->data));
264: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
265: CK((*filter->output_function)(c, filter->data));
266: } else {
267: w = (c1 << 8) | c;
268: w &= MBFL_WCSGROUP_MASK;
269: w |= MBFL_WCSGROUP_THROUGH;
270: CK((*filter->output_function)(w, filter->data));
271: }
272: break;
273:
274: case 2: /* got 0x8e : EUC-JP-2004 kana */
275: filter->status = 0;
276: if (c > 0xa0 && c < 0xe0) {
277: w = 0xfec0 + c;
278: CK((*filter->output_function)(w, filter->data));
279: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
280: CK((*filter->output_function)(c, filter->data));
281: } else {
282: w = 0x8e00 | c;
283: w &= MBFL_WCSGROUP_MASK;
284: w |= MBFL_WCSGROUP_THROUGH;
285: CK((*filter->output_function)(w, filter->data));
286: }
287: break;
288:
289: case 3: /* X 0213 plane 2 first char : EUC-JP-2004 (0x8f), ISO-2022-JP-2004 */
290: if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
291: CK((*filter->output_function)(c, filter->data));
292: filter->status = 0;
293: } else {
294: if (filter->from->no_encoding == mbfl_no_encoding_eucjp2004) {
295: s1 = c - 0x80;
296: } else {
297: s1 = c;
298: }
299: if (s1 > 0x20 && s1 < 0x80) {
300: filter->cache = s1;
301: filter->status++;
302: } else {
303: if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
304: w = c | 0x8f00;
305: w &= MBFL_WCSGROUP_MASK;
306: w |= MBFL_WCSGROUP_THROUGH;
307: } else {
308: w = c & 0x7f;
309: w &= MBFL_WCSPLANE_MASK;
310: w |= MBFL_WCSPLANE_JIS0213;
311: }
312: CK((*filter->output_function)(w, filter->data));
313: }
314: }
315: break;
316:
317: case 4: /* X 0213 plane 2 second char : EUC-JP-2004, ISO-2022-JP-2004 */
318:
319: filter->status &= ~0xf;
320: c1 = filter->cache;
321: if (filter->from->no_encoding == mbfl_no_encoding_eucjp2004) {
322: c2 = c - 0x80;
323: } else {
324: c2 = c;
325: }
326: s1 = c1 - 0x21;
327: s2 = c2 - 0x21;
328:
329: if (((s1 >= 0 && s1 <= 4 && s1 != 1) || s1 == 7 || (s1 >= 11 && s1 <= 14) ||
330: (s1 >= 77 && s1 < 94)) && s2 >= 0 && s2 < 94) {
331: /* calc offset from ku */
332: for (k = 0; k < jisx0213_p2_ofst_len; k++) {
333: if (s1 == jisx0213_p2_ofst[k]-1) {
334: break;
335: }
336: }
337: k = k - (jisx0213_p2_ofst[k]-1);
338:
339: /* check for japanese chars in BMP */
340: s = (s1 + 94 + k)*94 + s2;
341: if (s >= 0 && s < jisx0213_ucs_table_size) {
342: w = jisx0213_ucs_table[s];
343: } else {
344: w = 0;
345: }
346:
347: /* check for japanese chars in CJK Unified Ideographs ext.B (U+2XXXX) */
348: if (w <= 0) {
349: w1 = ((c1 + k + 94) << 8) | c2;
350: k = mbfl_bisec_srch2(w1, jisx0213_jis_u5_key, jisx0213_u5_tbl_len);
351: if (k >= 0) {
352: w = jisx0213_jis_u5_tbl[k] + 0x20000;
353: }
354: }
355:
356: if (w <= 0) {
357: w = ((c1 & 0x7f) << 8) | (c2 & 0x7f);
358: w &= MBFL_WCSPLANE_MASK;
359: w |= MBFL_WCSPLANE_JIS0213;
360: }
361:
362: CK((*filter->output_function)(w, filter->data));
363: } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
364: CK((*filter->output_function)(c, filter->data));
365: } else {
366: if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
367: w = (c1 << 8) | c | 0x8f0000;
368: w &= MBFL_WCSGROUP_MASK;
369: w |= MBFL_WCSGROUP_THROUGH;
370: } else {
371: w = ((c1 & 0x7f) << 8) | (c2 & 0x7f);
372: w &= MBFL_WCSPLANE_MASK;
373: w |= MBFL_WCSPLANE_JIS0213;
374: }
375: CK((*filter->output_function)(w, filter->data));
376: }
377:
378: break;
379:
380: case 5: /* X 0208 : ISO-2022-JP-2004 */
381: filter->status &= ~0xf;
382: c1 = filter->cache;
383: if (c > 0x20 && c < 0x7f) {
384: s = (c1 - 0x21)*94 + c - 0x21;
385: if (s >= 0 && s < jisx0208_ucs_table_size) {
386: w = jisx0208_ucs_table[s];
387: }
388: }
389: if (w <= 0) {
390: w = (c1 << 8) | c;
391: w &= MBFL_WCSPLANE_MASK;
392: w |= MBFL_WCSPLANE_JIS0208;
393: }
394: CK((*filter->output_function)(w, filter->data));
395: break;
396:
397: /* ESC : ISO-2022-JP-2004 */
398: /* case 0x06: */
399: /* case 0x16: */
400: /* case 0x26: */
401: /* case 0x86: */
402: /* case 0x96: */
403: /* case 0xa6: */
404: case 6:
405: if (c == 0x24) { /* '$' */
406: filter->status++;
407: } else if (c == 0x28) { /* '(' */
408: filter->status += 3;
409: } else {
410: filter->status &= ~0xf;
411: CK((*filter->output_function)(0x1b, filter->data));
412: goto retry;
413: }
414: break;
415:
416: /* ESC $ : ISO-2022-JP-2004 */
417: /* case 0x07: */
418: /* case 0x17: */
419: /* case 0x27: */
420: /* case 0x87: */
421: /* case 0x97: */
422: /* case 0xa7: */
423: case 7:
424: if (c == 0x42) { /* 'B' -> JIS X 0208-1983 */
425: filter->status = 0x80;
426: } else if (c == 0x28) { /* '(' */
427: filter->status++;
428: } else {
429: filter->status &= ~0xf;
430: CK((*filter->output_function)(0x1b, filter->data));
431: CK((*filter->output_function)(0x24, filter->data));
432: goto retry;
433: }
434: break;
435:
436: break;
437:
438: /* ESC $ ( : ISO-2022-JP-2004 */
439: /* case 0x08: */
440: /* case 0x18: */
441: /* case 0x28: */
442: /* case 0x88: */
443: /* case 0x98: */
444: /* case 0xa8: */
445: case 8:
446: if (c == 0x51) { /* JIS X 0213 plane 1 */
447: filter->status = 0x90;
448: } else if (c == 0x50) { /* JIS X 0213 plane 2 */
449: filter->status = 0xa0;
450: } else {
451: filter->status &= ~0xf;
452: CK((*filter->output_function)(0x1b, filter->data));
453: CK((*filter->output_function)(0x24, filter->data));
454: CK((*filter->output_function)(0x28, filter->data));
455: goto retry;
456: }
457: break;
458:
459: /* ESC ( : ISO-2022-JP-2004 */
460: /* case 0x09: */
461: /* case 0x19: */
462: /* case 0x29: */
463: /* case 0x89: */
464: /* case 0x99: */
465: case 9:
466: if (c == 0x42) { /* 'B' : ASCII */
467: filter->status = 0;
468: } else {
469: filter->status &= ~0xf;
470: CK((*filter->output_function)(0x1b, filter->data));
471: CK((*filter->output_function)(0x28, filter->data));
472: goto retry;
473: }
474: break;
475:
476: default:
477: filter->status = 0;
478: break;
479: }
480:
481: return c;
482: }
483:
484: int
485: mbfl_filt_conv_wchar_jis2004(int c, mbfl_convert_filter *filter) {
486: int k;
487: int c1, c2, s1 = 0, s2;
488:
489: retry:
490:
491: /* check for 1st char of combining characters */
492: if ((filter->status & 0xf)== 0 && (
493: c == 0x00E6 ||
494: (c >= 0x0254 && c <= 0x02E9) ||
495: (c >= 0x304B && c <= 0x3053) ||
496: (c >= 0x30AB && c <= 0x30C8) ||
497: c == 0x31F7)) {
498: for (k=0;k<jisx0213_u2_tbl_len;k++) {
499: if (c == jisx0213_u2_tbl[2*k]) {
500: filter->status++;
501: filter->cache = k;
502: return c;
503: }
504: }
505: }
506:
507: /* check for 2nd char of combining characters */
508: if ((filter->status & 0xf) == 1 &&
509: filter->cache >= 0 && filter->cache <= jisx0213_u2_tbl_len) {
510: k = filter->cache;
511: filter->status &= ~0xf;
512: filter->cache = 0;
513:
514: c1 = jisx0213_u2_tbl[2*k];
515: if ((c1 == 0x0254 || c1 == 0x028C || c1 == 0x0259 || c1 == 0x025A)
516: && c == 0x0301) {
517: k++;
518: }
519: if (c == jisx0213_u2_tbl[2*k+1]) {
520: s1 = jisx0213_u2_key[k];
521: } else { /* fallback */
522: s1 = jisx0213_u2_fb_tbl[k];
523:
524: if (filter->to->no_encoding == mbfl_no_encoding_sjis2004) {
525: c1 = (s1 >> 8) & 0xff;
526: c2 = s1 & 0xff;
527: SJIS_ENCODE(c1, c2, s1, s2);
528: } else if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
529: s2 = (s1 & 0xff) + 0x80;
530: s1 = ((s1 >> 8) & 0xff) + 0x80;
531: } else {
532: if (filter->status != 0x200) {
533: CK((*filter->output_function)(0x1b, filter->data));
534: CK((*filter->output_function)(0x24, filter->data));
535: CK((*filter->output_function)(0x28, filter->data));
536: CK((*filter->output_function)(0x51, filter->data));
537: }
538: filter->status = 0x200;
539:
540: s2 = s1 & 0x7f;
541: s1 = (s1 >> 8) & 0x7f;
542: }
543:
544: CK((*filter->output_function)(s1, filter->data));
545: CK((*filter->output_function)(s2, filter->data));
546: goto retry;
547: }
548: }
549:
550: /* check for major japanese chars: U+4E00 - U+9FFF */
551: if (s1 <= 0) {
552: for (k=0; k < uni2jis_tbl_len ;k++) {
553: if (c >= uni2jis_tbl_range[k][0] && c <= uni2jis_tbl_range[k][1]) {
554: s1 = uni2jis_tbl[k][c-uni2jis_tbl_range[k][0]];
555: break;
556: }
557: }
558: }
559:
560: /* check for japanese chars in compressed mapping area: U+1E00 - U+4DBF */
561: if (s1 <= 0 && c >= ucs_c1_jisx0213_min && c <= ucs_c1_jisx0213_max) {
562: k = mbfl_bisec_srch(c, ucs_c1_jisx0213_tbl, ucs_c1_jisx0213_tbl_len);
563: if (k >= 0) {
564: s1 = ucs_c1_jisx0213_ofst[k] + c - ucs_c1_jisx0213_tbl[2*k];
565: }
566: }
567:
568: /* check for japanese chars in CJK Unified Ideographs ext.B (U+2XXXX) */
569: if (s1 <= 0 && c >= jisx0213_u5_tbl_min && c <= jisx0213_u5_tbl_max) {
570: k = mbfl_bisec_srch2(c - 0x20000, jisx0213_u5_jis_key, jisx0213_u5_tbl_len);
571: if (k >= 0) {
572: s1 = jisx0213_u5_jis_tbl[k];
573: }
574: }
575:
576: if (s1 <= 0) {
577: /* CJK Compatibility Forms: U+FE30 - U+FE4F */
578: if (c == 0xfe45) {
579: s1 = 0x233e;
580: } else if (c == 0xfe46) {
581: s1 = 0x233d;
582: } else if (c >= 0xf91d && c <= 0xf9dc) {
583: /* CJK Compatibility Ideographs: U+F900 - U+F92A */
584: k = mbfl_bisec_srch2(c, ucs_r2b_jisx0213_cmap_key, ucs_r2b_jisx0213_cmap_len);
585: if (k >= 0) {
586: s1 = ucs_r2b_jisx0213_cmap_val[k];
587: }
588: }
589: }
590:
591: if (s1 <= 0) {
592: c1 = c & ~MBFL_WCSPLANE_MASK;
593: if (c1 == MBFL_WCSPLANE_JIS0213) {
594: s1 = c & MBFL_WCSPLANE_MASK;
595: }
596: if (c == 0) {
597: s1 = 0;
598: } else if (s1 <= 0) {
599: s1 = -1;
600: }
601: } else if (s1 >= 0x9980) {
602: s1 = -1;
603: }
604:
605: if (s1 >= 0) {
606: if (s1 < 0x80) { /* ASCII */
607: if (filter->to->no_encoding == mbfl_no_encoding_2022jp_2004 &&
608: (filter->status & 0xff00) != 0) {
609: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
610: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
611: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
612: }
613: filter->status = 0;
614: CK((*filter->output_function)(s1, filter->data));
615: } else if (s1 < 0x100) { /* latin or kana */
616: if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
617: CK((*filter->output_function)(0x8e, filter->data));
618: }
619: CK((*filter->output_function)(s1, filter->data));
620: } else if (s1 < 0x7f00) { /* X 0213 plane 1 */
621: if (filter->to->no_encoding == mbfl_no_encoding_sjis2004) {
622: c1 = (s1 >> 8) & 0xff;
623: c2 = s1 & 0xff;
624: SJIS_ENCODE(c1, c2, s1, s2);
625: } else if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
626: s2 = (s1 & 0xff) + 0x80;
627: s1 = ((s1 >> 8) & 0xff) + 0x80;
628: } else {
629: if ((filter->status & 0xff00) != 0x200) {
630: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
631: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
632: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
633: CK((*filter->output_function)(0x51, filter->data)); /* 'Q' */
634: }
635: filter->status = 0x200;
636: s2 = s1 & 0xff;
637: s1 = (s1 >> 8) & 0xff;
638: }
639: CK((*filter->output_function)(s1, filter->data));
640: CK((*filter->output_function)(s2, filter->data));
641: } else { /* X 0213 plane 2 */
642: if (filter->to->no_encoding == mbfl_no_encoding_sjis2004) {
643: c1 = (s1 >> 8) & 0xff;
644: c2 = s1 & 0xff;
645: SJIS_ENCODE(c1, c2, s1, s2);
646: } else {
647: s2 = s1 & 0xff;
648: k = ((s1 >> 8) & 0xff) - 0x7f;
649: if (k >= 0 && k < jisx0213_p2_ofst_len) {
650: s1 = jisx0213_p2_ofst[k] - 1 + 0x21;
651: }
652: if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
653: s2 |= 0x80;
654: s1 |= 0x80;
655: CK((*filter->output_function)(0x8f, filter->data));
656: } else {
657: if ((filter->status & 0xff00) != 0x200) {
658: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
659: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
660: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
661: CK((*filter->output_function)(0x50, filter->data)); /* 'P' */
662: }
663: filter->status = 0x200;
664: }
665: }
666:
667: CK((*filter->output_function)(s1, filter->data));
668: CK((*filter->output_function)(s2, filter->data));
669: }
670: } else {
671: if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
672: CK(mbfl_filt_conv_illegal_output(c, filter));
673: }
674: }
675: }
676:
677: int
678: mbfl_filt_conv_jis2004_flush(mbfl_convert_filter *filter)
679: {
680: int k, c1, c2, s1, s2;
681:
682: k = filter->cache;
683: filter->cache = 0;
684:
685: if (filter->status == 1 && k >= 0 && k <= jisx0213_u2_tbl_len) {
686: s1 = jisx0213_u2_fb_tbl[k];
687:
688: if (filter->to->no_encoding == mbfl_no_encoding_sjis2004) {
689: c1 = (s1 >> 8) & 0xff;
690: c2 = s1 & 0xff;
691: SJIS_ENCODE(c1, c2, s1, s2);
692: } else if (filter->to->no_encoding == mbfl_no_encoding_eucjp2004) {
693: s2 = (s1 & 0xff) | 0x80;
694: s1 = ((s1 >> 8) & 0xff) | 0x80;
695: } else {
696: s2 = s1 & 0x7f;
697: s1 = (s1 >> 8) & 0x7f;
698: if ((filter->status & 0xff00) != 0x200) {
699: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
700: CK((*filter->output_function)(0x24, filter->data)); /* '$' */
701: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
702: CK((*filter->output_function)(0x51, filter->data)); /* 'Q' */
703: }
704: filter->status = 0x200;
705: }
706:
707: CK((*filter->output_function)(s1, filter->data));
708: CK((*filter->output_function)(s2, filter->data));
709: }
710:
711: /* back to latin */
712: if ((filter->status & 0xff00) != 0) {
713: CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
714: CK((*filter->output_function)(0x28, filter->data)); /* '(' */
715: CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
716: }
717:
718: filter->status = 0;
719:
720: if (filter->flush_function != NULL) {
721: return (*filter->flush_function)(filter->data);
722: }
723:
724: return 0;
725: }