blob: 63d3b97ff92623ca1985b416b5b3aa06991c3626 [file] [log] [blame]
Ivan Nikulin58cecf12016-09-15 10:44:19 +02001/* Copyright 2016 Google Inc. All Rights Reserved.
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +02002 Author: zip753@gmail.com (Ivan Nikulin)
Ivan Nikulin58cecf12016-09-15 10:44:19 +02003
4 Distributed under MIT license.
5 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
6*/
7
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +02008/* API for reading distances from *.dist file.
9 The format of *.dist file is as follows: for each backward reference there is
10 a position-distance pair, also a copy length may be specified. Copy length is
11 prefixed with flag byte 0, position-distance pair is prefixed with flag
12 byte 1. Each number is a 32-bit integer. Copy length always comes before
13 position-distance pair. Standalone copy length is allowed, in this case it is
14 ignored. */
Ivan Nikulin58cecf12016-09-15 10:44:19 +020015
16#ifndef BROTLI_RESEARCH_READ_DIST_H_
17#define BROTLI_RESEARCH_READ_DIST_H_
18
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +020019#include <cstdio>
20#include <cstdlib> /* exit, EXIT_FAILURE */
21
Tianjie Xua5dcb7c2018-09-25 12:25:15 -070022#if !defined(CHECK)
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +020023#define CHECK(X) if (!(X)) exit(EXIT_FAILURE);
24#endif
25
Ivan Nikulin58cecf12016-09-15 10:44:19 +020026/* Reads backwards reference from .dist file. Sets all missing fields to -1.
27 Returns false when EOF is met or input is corrupt. */
28bool ReadBackwardReference(FILE* fin, int* copy, int* pos, int* dist) {
29 int c = getc(fin);
30 if (c == EOF) return false;
31 if (c == 0) {
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +020032 CHECK(fread(copy, sizeof(int), 1, fin) == 1);
Ivan Nikulin58cecf12016-09-15 10:44:19 +020033 if ((c = getc(fin)) != 1) {
34 ungetc(c, fin);
35 *pos = *dist = -1;
36 } else {
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +020037 CHECK(fread(pos, sizeof(int), 1, fin) == 1);
38 CHECK(fread(dist, sizeof(int), 1, fin) == 1);
Ivan Nikulin58cecf12016-09-15 10:44:19 +020039 }
40 } else if (c != 1) {
41 return false;
42 } else {
Eugene Kliuchnikovdd8fa3e2016-09-22 11:32:23 +020043 CHECK(fread(pos, sizeof(int), 1, fin) == 1);
44 CHECK(fread(dist, sizeof(int), 1, fin) == 1);
Ivan Nikulin58cecf12016-09-15 10:44:19 +020045 *copy = -1;
46 }
47 return true;
48}
49
50#endif /* BROTLI_RESEARCH_READ_DIST_H_ */