├── LICENSE
├── MD5.pas
├── PdfPageCount.pas
└── README.md
/LICENSE:
--------------------------------------------------------------------------------
1 | Boost Software License - Version 1.0 - August 17th, 2003
2 |
3 | Permission is hereby granted, free of charge, to any person or organization
4 | obtaining a copy of the software and accompanying documentation covered by
5 | this license (the "Software") to use, reproduce, display, distribute,
6 | execute, and transmit the Software, and to prepare derivative works of the
7 | Software, and to permit third-parties to whom the Software is furnished to
8 | do so, all subject to the following:
9 |
10 | The copyright notices in the Software and this entire statement, including
11 | the above license grant, this restriction and the following disclaimer,
12 | must be included in all copies of the Software, in whole or in part, and
13 | all derivative works of the Software, unless such copies or derivative
14 | works are solely in the form of machine-executable object code generated by
15 | a source language processor.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/MD5.pas:
--------------------------------------------------------------------------------
1 | unit MD5;
2 |
3 | (*******************************************************************************
4 | * *
5 | * Author : Angus Johnson *
6 | * Version : 1.2 *
7 | * Date : 12 February 2024 *
8 | * Website : http://www.angusj.com *
9 | * Copyright : Angus Johnson 2010-2024 *
10 | * *
11 | * License: *
12 | * Use, modification & distribution is subject to Boost Software License Ver 1. *
13 | * http://www.boost.org/LICENSE_1_0.txt *
14 | * *
15 | *******************************************************************************)
16 |
17 | interface
18 |
19 | {$Q-}
20 |
21 | uses
22 | Windows, SysUtils, Classes;
23 |
24 | const
25 | BuffLen64 = 64;
26 |
27 | type
28 | {$IFNDEF UNICODE}
29 | PByte = PChar;
30 | {$ENDIF}
31 | PByteArray = ^TByteArray;
32 | TByteArray = array[0..MaxInt-1] of Byte;
33 | TByteArray16 = array [0..15] of Byte;
34 |
35 | Md5Record = record
36 | private
37 | state : array [0..3] of cardinal;
38 | count : array [0..1] of cardinal;
39 | digest : TByteArray16;
40 | buffer64 : array [0..BuffLen64 -1] of Byte;
41 | procedure Transform;
42 |
43 | procedure F1(var a: cardinal; b, c, d, x, s: cardinal);
44 | procedure F2(var a: cardinal; b, c, d, x, s: cardinal);
45 | procedure F3(var a: cardinal; b, c, d, x, s: cardinal);
46 | procedure F4(var a: cardinal; b, c, d, x, s: cardinal);
47 | public
48 | procedure Init;
49 | procedure Update(start: PByteArray; length: cardinal);
50 | procedure Finalize;
51 | property Hash: TByteArray16 read digest;
52 | end;
53 |
54 | implementation
55 |
56 | //------------------------------------------------------------------------------
57 | //------------------------------------------------------------------------------
58 |
59 | procedure Md5Record.Init;
60 | begin
61 | count[0] := 0;
62 | count[1] := 0;
63 |
64 | //Load magic constants ...
65 | state[0] := $67452301;
66 | state[1] := $efcdab89;
67 | state[2] := $98badcfe;
68 | state[3] := $10325476;
69 | end;
70 | //------------------------------------------------------------------------------
71 |
72 | procedure Md5Record.Finalize;
73 | var
74 | cnt: cardinal;
75 | pb : system.PByte;
76 | begin
77 | cnt := (count[0] shr 3) and $3f;
78 | pb := @buffer64[cnt];
79 | pb^ := $80;
80 | inc(pb);
81 | cnt := 63 - cnt;
82 | if cnt < 8 then
83 | begin
84 | // Two lots of padding: Pad the first block to 64 bytes */
85 | FillChar(pb^, cnt, 0);
86 | Transform;
87 | // Now fill the next block with 56 bytes */
88 | FillChar(buffer64[0], 56, 0);
89 | end
90 | else if cnt > 8 then
91 | FillChar(pb^, cnt -8, 0);
92 |
93 | // Append length in bits and transform ...
94 | move(count[0], buffer64[56], 4);
95 | move(count[1], buffer64[60], 4);
96 | Transform;
97 | move(state[0], digest[0], 16);
98 | end;
99 | //------------------------------------------------------------------------------
100 |
101 | procedure Md5Record.Transform;
102 | var
103 | a,b,c,d: cardinal;
104 | x: array[0..15] of cardinal;
105 | begin
106 | Move(buffer64[0], x[0], BuffLen64);
107 | a := state[0]; b := state[1]; c := state[2]; d := state[3];
108 |
109 | // Round 1 ...
110 | F1 (a, b, c, d, x[ 0] + $d76aa478, 7);
111 | F1 (d, a, b, c, x[ 1] + $e8c7b756, 12);
112 | F1 (c, d, a, b, x[ 2] + $242070db, 17);
113 | F1 (b, c, d, a, x[ 3] + $c1bdceee, 22);
114 | F1 (a, b, c, d, x[ 4] + $f57c0faf, 7);
115 | F1 (d, a, b, c, x[ 5] + $4787c62a, 12);
116 | F1 (c, d, a, b, x[ 6] + $a8304613, 17);
117 | F1 (b, c, d, a, x[ 7] + $fd469501, 22);
118 | F1 (a, b, c, d, x[ 8] + $698098d8, 7);
119 | F1 (d, a, b, c, x[ 9] + $8b44f7af, 12);
120 | F1 (c, d, a, b, x[10] + $ffff5bb1, 17);
121 | F1 (b, c, d, a, x[11] + $895cd7be, 22);
122 | F1 (a, b, c, d, x[12] + $6b901122, 7);
123 | F1 (d, a, b, c, x[13] + $fd987193, 12);
124 | F1 (c, d, a, b, x[14] + $a679438e, 17);
125 | F1 (b, c, d, a, x[15] + $49b40821, 22);
126 |
127 | // Round 2 ...
128 | F2 (a, b, c, d, x[ 1] + $f61e2562, 5);
129 | F2 (d, a, b, c, x[ 6] + $c040b340, 9);
130 | F2 (c, d, a, b, x[11] + $265e5a51, 14);
131 | F2 (b, c, d, a, x[ 0] + $e9b6c7aa, 20);
132 | F2 (a, b, c, d, x[ 5] + $d62f105d, 5);
133 | F2 (d, a, b, c, x[10] + $02441453, 9);
134 | F2 (c, d, a, b, x[15] + $d8a1e681, 14);
135 | F2 (b, c, d, a, x[ 4] + $e7d3fbc8, 20);
136 | F2 (a, b, c, d, x[ 9] + $21e1cde6, 5);
137 | F2 (d, a, b, c, x[14] + $c33707d6, 9);
138 | F2 (c, d, a, b, x[ 3] + $f4d50d87, 14);
139 | F2 (b, c, d, a, x[ 8] + $455a14ed, 20);
140 | F2 (a, b, c, d, x[13] + $a9e3e905, 5);
141 | F2 (d, a, b, c, x[ 2] + $fcefa3f8, 9);
142 | F2 (c, d, a, b, x[ 7] + $676f02d9, 14);
143 | F2 (b, c, d, a, x[12] + $8d2a4c8a, 20);
144 |
145 | // Round 3 ..
146 | F3 (a, b, c, d, x[ 5] + $fffa3942, 4);
147 | F3 (d, a, b, c, x[ 8] + $8771f681, 11);
148 | F3 (c, d, a, b, x[11] + $6d9d6122, 16);
149 | F3 (b, c, d, a, x[14] + $fde5380c, 23);
150 | F3 (a, b, c, d, x[ 1] + $a4beea44, 4);
151 | F3 (d, a, b, c, x[ 4] + $4bdecfa9, 11);
152 | F3 (c, d, a, b, x[ 7] + $f6bb4b60, 16);
153 | F3 (b, c, d, a, x[10] + $bebfbc70, 23);
154 | F3 (a, b, c, d, x[13] + $289b7ec6, 4);
155 | F3 (d, a, b, c, x[ 0] + $eaa127fa, 11);
156 | F3 (c, d, a, b, x[ 3] + $d4ef3085, 16);
157 | F3 (b, c, d, a, x[ 6] + $4881d05, 23);
158 | F3 (a, b, c, d, x[ 9] + $d9d4d039, 4);
159 | F3 (d, a, b, c, x[12] + $e6db99e5, 11);
160 | F3 (c, d, a, b, x[15] + $1fa27cf8, 16);
161 | F3 (b, c, d, a, x[ 2] + $c4ac5665, 23);
162 |
163 | // Round 4 ..
164 | F4 (a, b, c, d, x[ 0] + $f4292244, 6);
165 | F4 (d, a, b, c, x[ 7] + $432aff97, 10);
166 | F4 (c, d, a, b, x[14] + $ab9423a7, 15);
167 | F4 (b, c, d, a, x[ 5] + $fc93a039, 21);
168 | F4 (a, b, c, d, x[12] + $655b59c3, 6);
169 | F4 (d, a, b, c, x[ 3] + $8f0ccc92, 10);
170 | F4 (c, d, a, b, x[10] + $ffeff47d, 15);
171 | F4 (b, c, d, a, x[ 1] + $85845dd1, 21);
172 | F4 (a, b, c, d, x[ 8] + $6fa87e4f, 6);
173 | F4 (d, a, b, c, x[15] + $fe2ce6e0, 10);
174 | F4 (c, d, a, b, x[ 6] + $a3014314, 15);
175 | F4 (b, c, d, a, x[13] + $4e0811a1, 21);
176 | F4 (a, b, c, d, x[ 4] + $f7537e82, 6);
177 | F4 (d, a, b, c, x[11] + $bd3af235, 10);
178 | F4 (c, d, a, b, x[ 2] + $2ad7d2bb, 15);
179 | F4 (b, c, d, a, x[ 9] + $eb86d391, 21);
180 |
181 | inc(state[0], a);
182 | inc(state[1], b);
183 | inc(state[2], c);
184 | inc(state[3], d);
185 | end;
186 | //------------------------------------------------------------------------------
187 |
188 | procedure Md5Record.Update(start: PByteArray; length: cardinal);
189 | var
190 | t, idx, spc: cardinal;
191 | //sl: TStringList;
192 | begin
193 |
194 | // Update number of bits
195 | t := count[0];
196 | count[0] := t + (length shl 3);
197 | if count[0] < t then inc(count[1]);
198 | inc(count[1], length shr 29);
199 |
200 | // Compute number of bytes mod 64
201 | idx := (t shr 3) and $3f;
202 | spc := BuffLen64 - idx;
203 |
204 | if idx > 0 then
205 | begin
206 | if (length < spc) then
207 | begin
208 | move(start^, buffer64[idx], length);
209 | exit;
210 | end;
211 | move(start^, buffer64[idx], spc);
212 | Transform;
213 | dec(length, spc);
214 | inc(PByte(start), spc);
215 | end;
216 |
217 | //Process data in 64-byte chunks ...
218 | while (length >= BuffLen64) do
219 | begin
220 | move(start^, buffer64[0], BuffLen64);
221 | Transform;
222 | dec(length, BuffLen64);
223 | inc(PByte(start), BuffLen64);
224 | end;
225 |
226 | //Finally, handle any remaining bytes of data ...
227 | move(start^, buffer64[0], length);
228 | end;
229 | //------------------------------------------------------------------------------
230 |
231 | procedure Md5Record.F1(var a: cardinal; b, c, d, x, s: cardinal);
232 | begin
233 | inc(a, (d xor (b and (c xor d))) + x);
234 | a := ((a shl s) or (a shr (32-s))) + b;
235 | end;
236 | //------------------------------------------------------------------------------
237 |
238 | procedure Md5Record.F2(var a: cardinal; b, c, d, x, s: cardinal);
239 | begin
240 | inc(a, ((b and d) or (c and not d)) + x);
241 | a := ((a shl s) or (a shr (32-s))) + b;
242 | end;
243 | //------------------------------------------------------------------------------
244 |
245 | procedure Md5Record.F3(var a: cardinal; b, c, d, x, s: cardinal);
246 | begin
247 | inc(a, (b xor c xor d) + x);
248 | a := ((a shl s) or (a shr (32-s))) + b;
249 | end;
250 | //------------------------------------------------------------------------------
251 |
252 | procedure Md5Record.F4(var a: cardinal; b, c, d, x, s: cardinal);
253 | begin
254 | inc(a, (c xor (b or not d)) + x);
255 | a := ((a shl s) or (a shr (32-s))) + b;
256 | end;
257 | //------------------------------------------------------------------------------
258 |
259 | end.
260 |
--------------------------------------------------------------------------------
/PdfPageCount.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AngusJohnson/PdfPageCount/4f25cbc02d898e0f0ae7b185ee57a92350f94459/PdfPageCount.pas
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PdfPageCount (Delphi only)
2 |
3 | **Limitation**: The PdfPageCount function will return -1 (no result) whenever PDF files are encrypted (ie have access protection).
4 |
5 | While this code isn't polished, it's quite functional.
6 |
--------------------------------------------------------------------------------