diff options
Diffstat (limited to 'xdelta3/xdelta3.c')
-rw-r--r-- | xdelta3/xdelta3.c | 480 |
1 files changed, 6 insertions, 474 deletions
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 78a331e..8513aac 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -294,16 +294,6 @@ | |||
294 | #endif | 294 | #endif |
295 | #endif | 295 | #endif |
296 | 296 | ||
297 | #ifndef GENERIC_ENCODE_TABLES /* These three are the RFC-spec app-specific */ | ||
298 | #define GENERIC_ENCODE_TABLES 0 /* code features. This is tested but not */ | ||
299 | #endif /* recommended unless there's a real use. */ | ||
300 | #ifndef GENERIC_ENCODE_TABLES_COMPUTE | ||
301 | #define GENERIC_ENCODE_TABLES_COMPUTE 0 | ||
302 | #endif | ||
303 | #ifndef GENERIC_ENCODE_TABLES_COMPUTE_PRINT | ||
304 | #define GENERIC_ENCODE_TABLES_COMPUTE_PRINT 0 | ||
305 | #endif | ||
306 | |||
307 | #if XD3_ENCODER | 297 | #if XD3_ENCODER |
308 | #define IF_ENCODER(x) x | 298 | #define IF_ENCODER(x) x |
309 | #else | 299 | #else |
@@ -559,8 +549,6 @@ static void xd3_verify_small_state (xd3_stream *stream, | |||
559 | static int xd3_decode_allocate (xd3_stream *stream, usize_t size, | 549 | static int xd3_decode_allocate (xd3_stream *stream, usize_t size, |
560 | uint8_t **copied1, usize_t *alloc1); | 550 | uint8_t **copied1, usize_t *alloc1); |
561 | 551 | ||
562 | static void xd3_compute_code_table_string (const xd3_dinst *code_table, | ||
563 | uint8_t *str); | ||
564 | static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); | 552 | static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); |
565 | static void xd3_free (xd3_stream *stream, void *ptr); | 553 | static void xd3_free (xd3_stream *stream, void *ptr); |
566 | 554 | ||
@@ -881,14 +869,10 @@ const uint16_t __single_hash[256] = | |||
881 | 869 | ||
882 | /* The XD3_CHOOSE_INSTRUCTION calls xd3_choose_instruction with the | 870 | /* The XD3_CHOOSE_INSTRUCTION calls xd3_choose_instruction with the |
883 | * table description when GENERIC_ENCODE_TABLES are in use. The | 871 | * table description when GENERIC_ENCODE_TABLES are in use. The |
884 | * IF_GENCODETBL macro enables generic-code-table specific code. */ | 872 | * IF_GENCODETBL macro enables generic-code-table specific code |
885 | #if GENERIC_ENCODE_TABLES | 873 | * (removed 10/2014). */ |
886 | #define XD3_CHOOSE_INSTRUCTION(stream,prev,inst) xd3_choose_instruction (stream->code_table_desc, prev, inst) | 874 | #define XD3_CHOOSE_INSTRUCTION(stream,prev,inst) \ |
887 | #define IF_GENCODETBL(x) x | 875 | xd3_choose_instruction (prev, inst) |
888 | #else | ||
889 | #define XD3_CHOOSE_INSTRUCTION(stream,prev,inst) xd3_choose_instruction (prev, inst) | ||
890 | #define IF_GENCODETBL(x) | ||
891 | #endif | ||
892 | 876 | ||
893 | /* This structure maintains information needed by | 877 | /* This structure maintains information needed by |
894 | * xd3_choose_instruction to compute the code for a double instruction | 878 | * xd3_choose_instruction to compute the code for a double instruction |
@@ -950,50 +934,6 @@ static const xd3_code_table_desc __rfc3284_code_table_desc = { | |||
950 | { {4,247,1},{4,248,1},{4,249,1},{4,250,1},{4,251,1},{4,252,1},{4,253,1},{4,254,1},{4,255,1} }, | 934 | { {4,247,1},{4,248,1},{4,249,1},{4,250,1},{4,251,1},{4,252,1},{4,253,1},{4,254,1},{4,255,1} }, |
951 | }; | 935 | }; |
952 | 936 | ||
953 | #if GENERIC_ENCODE_TABLES | ||
954 | /* An alternate code table for testing (5 near, 0 same): | ||
955 | * | ||
956 | * TYPE SIZE MODE TYPE SIZE MODE INDEX | ||
957 | * --------------------------------------------------------------- | ||
958 | * 1. Run 0 0 Noop 0 0 0 | ||
959 | * 2. Add 0, [1,23] 0 Noop 0 0 [1,24] | ||
960 | * 3. Copy 0, [4,20] 0 Noop 0 0 [25,42] | ||
961 | * 4. Copy 0, [4,20] 1 Noop 0 0 [43,60] | ||
962 | * 5. Copy 0, [4,20] 2 Noop 0 0 [61,78] | ||
963 | * 6. Copy 0, [4,20] 3 Noop 0 0 [79,96] | ||
964 | * 7. Copy 0, [4,20] 4 Noop 0 0 [97,114] | ||
965 | * 8. Copy 0, [4,20] 5 Noop 0 0 [115,132] | ||
966 | * 9. Copy 0, [4,20] 6 Noop 0 0 [133,150] | ||
967 | * 10. Add [1,4] 0 Copy [4,6] 0 [151,162] | ||
968 | * 11. Add [1,4] 0 Copy [4,6] 1 [163,174] | ||
969 | * 12. Add [1,4] 0 Copy [4,6] 2 [175,186] | ||
970 | * 13. Add [1,4] 0 Copy [4,6] 3 [187,198] | ||
971 | * 14. Add [1,4] 0 Copy [4,6] 4 [199,210] | ||
972 | * 15. Add [1,4] 0 Copy [4,6] 5 [211,222] | ||
973 | * 16. Add [1,4] 0 Copy [4,6] 6 [223,234] | ||
974 | * 17. Copy 4 [0,6] Add [1,3] 0 [235,255] | ||
975 | * --------------------------------------------------------------- */ | ||
976 | static const xd3_code_table_desc __alternate_code_table_desc = { | ||
977 | 23, /* add sizes */ | ||
978 | 5, /* near modes */ | ||
979 | 0, /* same modes */ | ||
980 | 17, /* copy sizes */ | ||
981 | |||
982 | 4, /* add-copy max add */ | ||
983 | 6, /* add-copy max cpy, near */ | ||
984 | 0, /* add-copy max cpy, same */ | ||
985 | |||
986 | 3, /* copy-add max add */ | ||
987 | 4, /* copy-add max cpy, near */ | ||
988 | 0, /* copy-add max cpy, same */ | ||
989 | |||
990 | /* addcopy */ | ||
991 | { {6,151,3},{6,163,3},{6,175,3},{6,187,3},{6,199,3},{6,211,3},{6,223,3},{0,0,0},{0,0,0} }, | ||
992 | /* copyadd */ | ||
993 | { {4,235,1},{4,238,1},{4,241,1},{4,244,1},{4,247,1},{4,250,1},{4,253,1},{0,0,0},{0,0,0} }, | ||
994 | }; | ||
995 | #endif | ||
996 | |||
997 | /* Computes code table entries of TBL using the specified description. */ | 937 | /* Computes code table entries of TBL using the specified description. */ |
998 | static void | 938 | static void |
999 | xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) | 939 | xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) |
@@ -1076,117 +1016,6 @@ xd3_rfc3284_code_table (void) | |||
1076 | } | 1016 | } |
1077 | 1017 | ||
1078 | #if XD3_ENCODER | 1018 | #if XD3_ENCODER |
1079 | #if GENERIC_ENCODE_TABLES | ||
1080 | /* This function generates the alternate code table. */ | ||
1081 | static const xd3_dinst* | ||
1082 | xd3_alternate_code_table (void) | ||
1083 | { | ||
1084 | static xd3_dinst __alternate_code_table[256]; | ||
1085 | |||
1086 | if (__alternate_code_table[0].type1 != XD3_RUN) | ||
1087 | { | ||
1088 | xd3_build_code_table (& __alternate_code_table_desc, __alternate_code_table); | ||
1089 | } | ||
1090 | |||
1091 | return __alternate_code_table; | ||
1092 | } | ||
1093 | |||
1094 | /* This function computes the ideal second instruction INST based on | ||
1095 | * preceding instruction PREV. If it is possible to issue a double | ||
1096 | * instruction based on this pair it sets PREV->code2, otherwise it | ||
1097 | * sets INST->code1. */ | ||
1098 | static void | ||
1099 | xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_rinst *inst) | ||
1100 | { | ||
1101 | switch (inst->type) | ||
1102 | { | ||
1103 | case XD3_RUN: | ||
1104 | /* The 0th instruction is RUN */ | ||
1105 | inst->code1 = 0; | ||
1106 | break; | ||
1107 | |||
1108 | case XD3_ADD: | ||
1109 | |||
1110 | if (inst->size > desc->add_sizes) | ||
1111 | { | ||
1112 | /* The first instruction is non-immediate ADD */ | ||
1113 | inst->code1 = 1; | ||
1114 | } | ||
1115 | else | ||
1116 | { | ||
1117 | /* The following ADD_SIZES instructions are immediate ADDs */ | ||
1118 | inst->code1 = 1 + inst->size; | ||
1119 | |||
1120 | /* Now check for a possible COPY-ADD double instruction */ | ||
1121 | if (prev != NULL) | ||
1122 | { | ||
1123 | int prev_mode = prev->type - XD3_CPY; | ||
1124 | |||
1125 | /* If previous is a copy. Note: as long as the previous | ||
1126 | * is not a RUN instruction, it should be a copy because | ||
1127 | * it cannot be an add. This check is more clear. */ | ||
1128 | if (prev_mode >= 0 && inst->size <= desc->copyadd_add_max) | ||
1129 | { | ||
1130 | const xd3_code_table_sizes *sizes = | ||
1131 | & desc->copyadd_max_sizes[prev_mode]; | ||
1132 | |||
1133 | /* This check and the inst->size-<= above are == in | ||
1134 | the default table. */ | ||
1135 | if (prev->size <= sizes->cpy_max) | ||
1136 | { | ||
1137 | /* The second and third exprs are 0 in the | ||
1138 | default table. */ | ||
1139 | prev->code2 = sizes->offset + | ||
1140 | (sizes->mult * (prev->size - MIN_MATCH)) + | ||
1141 | (inst->size - MIN_ADD); | ||
1142 | } | ||
1143 | } | ||
1144 | } | ||
1145 | } | ||
1146 | break; | ||
1147 | |||
1148 | default: | ||
1149 | { | ||
1150 | int mode = inst->type - XD3_CPY; | ||
1151 | |||
1152 | /* The large copy instruction is offset by the run, large add, | ||
1153 | * and immediate adds, then multipled by the number of | ||
1154 | * immediate copies plus one (the large copy) (i.e., if there | ||
1155 | * are 15 immediate copy instructions then there are 16 copy | ||
1156 | * instructions per mode). */ | ||
1157 | inst->code1 = 2 + desc->add_sizes + (1 + desc->cpy_sizes) * mode; | ||
1158 | |||
1159 | /* Now if the copy is short enough for an immediate instruction. */ | ||
1160 | if (inst->size < MIN_MATCH + desc->cpy_sizes && | ||
1161 | /* TODO: there needs to be a more comprehensive test for this | ||
1162 | * boundary condition, merge is now exercising code in which | ||
1163 | * size < MIN_MATCH is possible and it's unclear if the above | ||
1164 | * size < (MIN_MATCH + cpy_sizes) should be a <= from inspection | ||
1165 | * of the default table version below. */ | ||
1166 | inst->size >= MIN_MATCH) | ||
1167 | { | ||
1168 | inst->code1 += inst->size + 1 - MIN_MATCH; | ||
1169 | |||
1170 | /* Now check for a possible ADD-COPY double instruction. */ | ||
1171 | if ( (prev != NULL) && | ||
1172 | (prev->type == XD3_ADD) && | ||
1173 | (prev->size <= desc->addcopy_add_max) ) | ||
1174 | { | ||
1175 | const xd3_code_table_sizes *sizes = & desc->addcopy_max_sizes[mode]; | ||
1176 | |||
1177 | if (inst->size <= sizes->cpy_max) | ||
1178 | { | ||
1179 | prev->code2 = sizes->offset + | ||
1180 | (sizes->mult * (prev->size - MIN_ADD)) + | ||
1181 | (inst->size - MIN_MATCH); | ||
1182 | } | ||
1183 | } | ||
1184 | } | ||
1185 | } | ||
1186 | } | ||
1187 | } | ||
1188 | #else /* GENERIC_ENCODE_TABLES */ | ||
1189 | |||
1190 | /* This version of xd3_choose_instruction is hard-coded for the default | 1019 | /* This version of xd3_choose_instruction is hard-coded for the default |
1191 | table. */ | 1020 | table. */ |
1192 | static void | 1021 | static void |
@@ -1254,262 +1083,8 @@ xd3_choose_instruction (xd3_rinst *prev, xd3_rinst *inst) | |||
1254 | break; | 1083 | break; |
1255 | } | 1084 | } |
1256 | } | 1085 | } |
1257 | #endif /* GENERIC_ENCODE_TABLES */ | ||
1258 | |||
1259 | /*********************************************************************** | ||
1260 | Instruction table encoder/decoder | ||
1261 | ***********************************************************************/ | ||
1262 | |||
1263 | #if GENERIC_ENCODE_TABLES | ||
1264 | #if GENERIC_ENCODE_TABLES_COMPUTE == 0 | ||
1265 | |||
1266 | /* In this case, we hard-code the result of | ||
1267 | * compute_code_table_encoding for each alternate code table, | ||
1268 | * presuming that saves time/space. This has been 131 bytes, but | ||
1269 | * secondary compression was turned off. */ | ||
1270 | static const uint8_t __alternate_code_table_compressed[178] = | ||
1271 | {0xd6,0xc3,0xc4,0x00,0x00,0x01,0x8a,0x6f,0x40,0x81,0x27,0x8c,0x00,0x00,0x4a,0x4a,0x0d,0x02,0x01,0x03, | ||
1272 | 0x01,0x03,0x00,0x01,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, | ||
1273 | 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04, | ||
1274 | 0x04,0x04,0x04,0x00,0x04,0x05,0x06,0x01,0x02,0x03,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x05,0x05,0x05, | ||
1275 | 0x06,0x06,0x06,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x00,0x02,0x00,0x18,0x13,0x63,0x00,0x1b,0x00,0x54, | ||
1276 | 0x00,0x15,0x23,0x6f,0x00,0x28,0x13,0x54,0x00,0x15,0x01,0x1a,0x31,0x23,0x6c,0x0d,0x23,0x48,0x00,0x15, | ||
1277 | 0x93,0x6f,0x00,0x28,0x04,0x23,0x51,0x04,0x32,0x00,0x2b,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, | ||
1278 | 0x12,0x00,0x12,0x53,0x57,0x9c,0x07,0x43,0x6f,0x00,0x34,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00, | ||
1279 | 0x0c,0x00,0x0c,0x00,0x15,0x00,0x82,0x6f,0x00,0x15,0x12,0x0c,0x00,0x03,0x03,0x00,0x06,0x00,}; | ||
1280 | |||
1281 | static int | ||
1282 | xd3_compute_alternate_table_encoding (xd3_stream *stream, const uint8_t **data, usize_t *size) | ||
1283 | { | ||
1284 | (*data) = __alternate_code_table_compressed; | ||
1285 | (*size) = sizeof (__alternate_code_table_compressed); | ||
1286 | return 0; | ||
1287 | } | ||
1288 | |||
1289 | #else | ||
1290 | |||
1291 | /* The alternate code table will be computed and stored here. */ | ||
1292 | static uint8_t __alternate_code_table_compressed[CODE_TABLE_VCDIFF_SIZE]; | ||
1293 | static usize_t __alternate_code_table_compressed_size; | ||
1294 | |||
1295 | /* This function generates a delta describing the code table for | ||
1296 | * encoding within a VCDIFF file. This function is NOT thread safe | ||
1297 | * because it is only intended that this function is used to generate | ||
1298 | * statically-compiled strings. "comp_string" must be sized | ||
1299 | * CODE_TABLE_VCDIFF_SIZE. */ | ||
1300 | int xd3_compute_code_table_encoding (xd3_stream *in_stream, | ||
1301 | const xd3_dinst *code_table, | ||
1302 | uint8_t *comp_string, | ||
1303 | usize_t *comp_string_size) | ||
1304 | { | ||
1305 | /* Use DJW secondary compression if it is on by default. This saves | ||
1306 | * about 20 bytes. */ | ||
1307 | uint8_t dflt_string[CODE_TABLE_STRING_SIZE]; | ||
1308 | uint8_t code_string[CODE_TABLE_STRING_SIZE]; | ||
1309 | |||
1310 | xd3_compute_code_table_string (xd3_rfc3284_code_table (), dflt_string); | ||
1311 | xd3_compute_code_table_string (code_table, code_string); | ||
1312 | |||
1313 | return xd3_encode_memory (code_string, CODE_TABLE_STRING_SIZE, | ||
1314 | dflt_string, CODE_TABLE_STRING_SIZE, | ||
1315 | comp_string, comp_string_size, | ||
1316 | CODE_TABLE_VCDIFF_SIZE, | ||
1317 | /* flags */ 0); | ||
1318 | } | ||
1319 | |||
1320 | /* Compute a delta between alternate and rfc3284 tables. As soon as | ||
1321 | * another alternate table is added, this code should become generic. | ||
1322 | * For now there is only one alternate table for testing. */ | ||
1323 | static int | ||
1324 | xd3_compute_alternate_table_encoding (xd3_stream *stream, const uint8_t **data, usize_t *size) | ||
1325 | { | ||
1326 | int ret; | ||
1327 | |||
1328 | if (__alternate_code_table_compressed[0] == 0) | ||
1329 | { | ||
1330 | if ((ret = xd3_compute_code_table_encoding (stream, xd3_alternate_code_table (), | ||
1331 | __alternate_code_table_compressed, | ||
1332 | & __alternate_code_table_compressed_size))) | ||
1333 | { | ||
1334 | return ret; | ||
1335 | } | ||
1336 | |||
1337 | /* During development of a new code table, enable this variable to print | ||
1338 | * the new static contents and determine its size. At run time the | ||
1339 | * table will be filled in appropriately, but at least it should have | ||
1340 | * the proper size beforehand. */ | ||
1341 | #if GENERIC_ENCODE_TABLES_COMPUTE_PRINT | ||
1342 | { | ||
1343 | int i; | ||
1344 | |||
1345 | DP(RINT, "\nstatic const usize_t __alternate_code_table_compressed_size = %u;\n", | ||
1346 | __alternate_code_table_compressed_size); | ||
1347 | |||
1348 | DP(RINT, "static const uint8_t __alternate_code_table_compressed[%u] =\n{", | ||
1349 | __alternate_code_table_compressed_size); | ||
1350 | |||
1351 | for (i = 0; i < __alternate_code_table_compressed_size; i += 1) | ||
1352 | { | ||
1353 | DP(RINT, "0x%02x,", __alternate_code_table_compressed[i]); | ||
1354 | if ((i % 20) == 19) { DP(RINT, "\n"); } | ||
1355 | } | ||
1356 | |||
1357 | DP(RINT, "};\n"); | ||
1358 | } | ||
1359 | #endif | ||
1360 | } | ||
1361 | |||
1362 | (*data) = __alternate_code_table_compressed; | ||
1363 | (*size) = __alternate_code_table_compressed_size; | ||
1364 | |||
1365 | return 0; | ||
1366 | } | ||
1367 | #endif /* GENERIC_ENCODE_TABLES_COMPUTE != 0 */ | ||
1368 | #endif /* GENERIC_ENCODE_TABLES */ | ||
1369 | |||
1370 | #endif /* XD3_ENCODER */ | 1086 | #endif /* XD3_ENCODER */ |
1371 | 1087 | ||
1372 | /* This function generates the 1536-byte string specified in sections 5.4 and | ||
1373 | * 7 of rfc3284, which is used to represent a code table within a VCDIFF | ||
1374 | * file. */ | ||
1375 | void xd3_compute_code_table_string (const xd3_dinst *code_table, uint8_t *str) | ||
1376 | { | ||
1377 | int i, s; | ||
1378 | |||
1379 | XD3_ASSERT (CODE_TABLE_STRING_SIZE == 6 * 256); | ||
1380 | |||
1381 | for (s = 0; s < 6; s += 1) | ||
1382 | { | ||
1383 | for (i = 0; i < 256; i += 1) | ||
1384 | { | ||
1385 | switch (s) | ||
1386 | { | ||
1387 | case 0: *str++ = (code_table[i].type1 >= XD3_CPY ? XD3_CPY : code_table[i].type1); break; | ||
1388 | case 1: *str++ = (code_table[i].type2 >= XD3_CPY ? XD3_CPY : code_table[i].type2); break; | ||
1389 | case 2: *str++ = (code_table[i].size1); break; | ||
1390 | case 3: *str++ = (code_table[i].size2); break; | ||
1391 | case 4: *str++ = (code_table[i].type1 >= XD3_CPY ? code_table[i].type1 - XD3_CPY : 0); break; | ||
1392 | case 5: *str++ = (code_table[i].type2 >= XD3_CPY ? code_table[i].type2 - XD3_CPY : 0); break; | ||
1393 | } | ||
1394 | } | ||
1395 | } | ||
1396 | } | ||
1397 | |||
1398 | /* This function translates the code table string into the internal representation. The | ||
1399 | * stream's near and same-modes should already be set. */ | ||
1400 | static int | ||
1401 | xd3_apply_table_string (xd3_stream *stream, const uint8_t *code_string) | ||
1402 | { | ||
1403 | int i, s; | ||
1404 | int modes = TOTAL_MODES (stream); | ||
1405 | xd3_dinst *code_table; | ||
1406 | |||
1407 | if ((code_table = stream->code_table_alloc = | ||
1408 | (xd3_dinst*) xd3_alloc (stream, | ||
1409 | (usize_t) sizeof (xd3_dinst), | ||
1410 | 256)) == NULL) | ||
1411 | { | ||
1412 | return ENOMEM; | ||
1413 | } | ||
1414 | |||
1415 | for (s = 0; s < 6; s += 1) | ||
1416 | { | ||
1417 | for (i = 0; i < 256; i += 1) | ||
1418 | { | ||
1419 | switch (s) | ||
1420 | { | ||
1421 | case 0: | ||
1422 | if (*code_string > XD3_CPY) | ||
1423 | { | ||
1424 | stream->msg = "invalid code-table opcode"; | ||
1425 | return XD3_INTERNAL; | ||
1426 | } | ||
1427 | code_table[i].type1 = *code_string++; | ||
1428 | break; | ||
1429 | case 1: | ||
1430 | if (*code_string > XD3_CPY) | ||
1431 | { | ||
1432 | stream->msg = "invalid code-table opcode"; | ||
1433 | return XD3_INTERNAL; | ||
1434 | } | ||
1435 | code_table[i].type2 = *code_string++; | ||
1436 | break; | ||
1437 | case 2: | ||
1438 | if (*code_string != 0 && code_table[i].type1 == XD3_NOOP) | ||
1439 | { | ||
1440 | stream->msg = "invalid code-table size"; | ||
1441 | return XD3_INTERNAL; | ||
1442 | } | ||
1443 | code_table[i].size1 = *code_string++; | ||
1444 | break; | ||
1445 | case 3: | ||
1446 | if (*code_string != 0 && code_table[i].type2 == XD3_NOOP) | ||
1447 | { | ||
1448 | stream->msg = "invalid code-table size"; | ||
1449 | return XD3_INTERNAL; | ||
1450 | } | ||
1451 | code_table[i].size2 = *code_string++; | ||
1452 | break; | ||
1453 | case 4: | ||
1454 | if (*code_string >= modes) | ||
1455 | { | ||
1456 | stream->msg = "invalid code-table mode"; | ||
1457 | return XD3_INTERNAL; | ||
1458 | } | ||
1459 | if (*code_string != 0 && code_table[i].type1 != XD3_CPY) | ||
1460 | { | ||
1461 | stream->msg = "invalid code-table mode"; | ||
1462 | return XD3_INTERNAL; | ||
1463 | } | ||
1464 | code_table[i].type1 += *code_string++; | ||
1465 | break; | ||
1466 | case 5: | ||
1467 | if (*code_string >= modes) | ||
1468 | { | ||
1469 | stream->msg = "invalid code-table mode"; | ||
1470 | return XD3_INTERNAL; | ||
1471 | } | ||
1472 | if (*code_string != 0 && code_table[i].type2 != XD3_CPY) | ||
1473 | { | ||
1474 | stream->msg = "invalid code-table mode"; | ||
1475 | return XD3_INTERNAL; | ||
1476 | } | ||
1477 | code_table[i].type2 += *code_string++; | ||
1478 | break; | ||
1479 | } | ||
1480 | } | ||
1481 | } | ||
1482 | |||
1483 | stream->code_table = code_table; | ||
1484 | return 0; | ||
1485 | } | ||
1486 | |||
1487 | /* This function applies a code table delta and returns an actual code table. */ | ||
1488 | static int | ||
1489 | xd3_apply_table_encoding (xd3_stream *in_stream, const uint8_t *data, usize_t size) | ||
1490 | { | ||
1491 | uint8_t dflt_string[CODE_TABLE_STRING_SIZE]; | ||
1492 | uint8_t code_string[CODE_TABLE_STRING_SIZE]; | ||
1493 | usize_t code_size; | ||
1494 | int ret; | ||
1495 | |||
1496 | xd3_compute_code_table_string (xd3_rfc3284_code_table (), dflt_string); | ||
1497 | |||
1498 | if ((ret = xd3_decode_memory (data, size, | ||
1499 | dflt_string, CODE_TABLE_STRING_SIZE, | ||
1500 | code_string, &code_size, | ||
1501 | CODE_TABLE_STRING_SIZE, | ||
1502 | 0))) { return ret; } | ||
1503 | |||
1504 | if (code_size != sizeof (code_string)) | ||
1505 | { | ||
1506 | in_stream->msg = "corrupt code-table encoding"; | ||
1507 | return XD3_INTERNAL; | ||
1508 | } | ||
1509 | |||
1510 | return xd3_apply_table_string (in_stream, code_string); | ||
1511 | } | ||
1512 | |||
1513 | /***********************************************************************/ | 1088 | /***********************************************************************/ |
1514 | 1089 | ||
1515 | static inline void | 1090 | static inline void |
@@ -2438,23 +2013,8 @@ xd3_config_stream(xd3_stream *stream, | |||
2438 | return XD3_INTERNAL; | 2013 | return XD3_INTERNAL; |
2439 | } | 2014 | } |
2440 | 2015 | ||
2441 | /* Check/set encoder code table. */ | 2016 | stream->code_table_desc = & __rfc3284_code_table_desc; |
2442 | switch (stream->flags & XD3_ALT_CODE_TABLE) { | 2017 | stream->code_table_func = xd3_rfc3284_code_table; |
2443 | case 0: | ||
2444 | stream->code_table_desc = & __rfc3284_code_table_desc; | ||
2445 | stream->code_table_func = xd3_rfc3284_code_table; | ||
2446 | break; | ||
2447 | #if GENERIC_ENCODE_TABLES | ||
2448 | case XD3_ALT_CODE_TABLE: | ||
2449 | stream->code_table_desc = & __alternate_code_table_desc; | ||
2450 | stream->code_table_func = xd3_alternate_code_table; | ||
2451 | stream->comp_table_func = xd3_compute_alternate_table_encoding; | ||
2452 | break; | ||
2453 | #endif | ||
2454 | default: | ||
2455 | stream->msg = "alternate code table support was not compiled"; | ||
2456 | return XD3_INTERNAL; | ||
2457 | } | ||
2458 | 2018 | ||
2459 | /* Check sprevsz */ | 2019 | /* Check sprevsz */ |
2460 | if (smatcher->small_chain == 1 && | 2020 | if (smatcher->small_chain == 1 && |
@@ -3420,11 +2980,8 @@ xd3_emit_hdr (xd3_stream *stream) | |||
3420 | { | 2980 | { |
3421 | usize_t hdr_ind = 0; | 2981 | usize_t hdr_ind = 0; |
3422 | int use_appheader = stream->enc_appheader != NULL; | 2982 | int use_appheader = stream->enc_appheader != NULL; |
3423 | int use_gencodetbl = GENERIC_ENCODE_TABLES && | ||
3424 | (stream->code_table_desc != & __rfc3284_code_table_desc); | ||
3425 | 2983 | ||
3426 | if (use_secondary) { hdr_ind |= VCD_SECONDARY; } | 2984 | if (use_secondary) { hdr_ind |= VCD_SECONDARY; } |
3427 | if (use_gencodetbl) { hdr_ind |= VCD_CODETABLE; } | ||
3428 | if (use_appheader) { hdr_ind |= VCD_APPHEADER; } | 2985 | if (use_appheader) { hdr_ind |= VCD_APPHEADER; } |
3429 | 2986 | ||
3430 | if ((ret = xd3_emit_byte (stream, & HDR_TAIL (stream), | 2987 | if ((ret = xd3_emit_byte (stream, & HDR_TAIL (stream), |
@@ -3450,31 +3007,6 @@ xd3_emit_hdr (xd3_stream *stream) | |||
3450 | } | 3007 | } |
3451 | #endif | 3008 | #endif |
3452 | 3009 | ||
3453 | /* Compressed code table */ | ||
3454 | if (use_gencodetbl) | ||
3455 | { | ||
3456 | usize_t code_table_size; | ||
3457 | const uint8_t *code_table_data; | ||
3458 | |||
3459 | if ((ret = stream->comp_table_func (stream, & code_table_data, | ||
3460 | & code_table_size))) | ||
3461 | { | ||
3462 | return ret; | ||
3463 | } | ||
3464 | |||
3465 | if ((ret = xd3_emit_size (stream, & HDR_TAIL (stream), | ||
3466 | code_table_size + 2)) || | ||
3467 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), | ||
3468 | stream->code_table_desc->near_modes)) || | ||
3469 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), | ||
3470 | stream->code_table_desc->same_modes)) || | ||
3471 | (ret = xd3_emit_bytes (stream, & HDR_TAIL (stream), | ||
3472 | code_table_data, code_table_size))) | ||
3473 | { | ||
3474 | return ret; | ||
3475 | } | ||
3476 | } | ||
3477 | |||
3478 | /* Application header */ | 3010 | /* Application header */ |
3479 | if (use_appheader) | 3011 | if (use_appheader) |
3480 | { | 3012 | { |