3 { This file contains simple error-reporting and trace-message routines.
4 These are suitable for Unix-like systems and others where writing to
5 stderr is the right thing to do. Many applications will want to replace
6 some or all of these routines.
8 These routines are used by both the compression and decompression code. }
10 { Source: jerror.c; Copyright (C) 1991-1996, Thomas G. Lane. }
11 { note: format_message still contains a hack }
25 EXIT_FAILURE
= 1; { define halt() codes if not provided }
28 function jpeg_std_error (var err
: jpeg_error_mgr
) : jpeg_error_mgr_ptr
;
32 procedure ERREXIT(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
);
34 procedure ERREXIT1(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
; p1
: uInt
);
36 procedure ERREXIT2(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
; p1
: int
; p2
: int
);
38 procedure ERREXIT3(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
39 p1
: int
; p2
: int
; p3
: int
);
41 procedure ERREXIT4(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
42 p1
: int
; p2
: int
; p3
: int
; p4
: int
);
44 procedure ERREXITS(cinfo
: j_common_ptr
;code
: J_MESSAGE_CODE
;
46 { Nonfatal errors (we can keep going, but the data is probably corrupt) }
48 procedure WARNMS(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
);
50 procedure WARNMS1(cinfo
: j_common_ptr
;code
: J_MESSAGE_CODE
; p1
: int
);
52 procedure WARNMS2(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
55 { Informational/debugging messages }
56 procedure TRACEMS(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
);
58 procedure TRACEMS1(cinfo
: j_common_ptr
; lvl
: int
;
59 code
: J_MESSAGE_CODE
; p1
: long
);
61 procedure TRACEMS2(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
65 procedure TRACEMS3(cinfo
: j_common_ptr
;
67 code
: J_MESSAGE_CODE
;
68 p1
: int
; p2
: int
; p3
: int
);
70 procedure TRACEMS4(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
71 p1
: int
; p2
: int
; p3
: int
; p4
: int
);
73 procedure TRACEMS5(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
74 p1
: int
; p2
: int
; p3
: int
; p4
: int
; p5
: int
);
76 procedure TRACEMS8(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
77 p1
: int
; p2
: int
; p3
: int
; p4
: int
;
78 p5
: int
; p6
: int
; p7
: int
; p8
: int
);
80 procedure TRACEMSS(cinfo
: j_common_ptr
; lvl
: int
;
81 code
: J_MESSAGE_CODE
; str
: AnsiString);
86 { How to format a message string, in format_message() ? }
98 drivers
, { Turbo Vision unit with FormatStr }
100 sysutils
, { Delphi Unit with Format() }
105 { Error exit handler: must not return to caller.
107 Applications may override this if they want to get control back after
108 an error. Typically one would longjmp somewhere instead of exiting.
109 The setjmp buffer can be made a private field within an expanded error
110 handler object. Note that the info needed to generate an error message
111 is stored in the error object, so you can generate the message now or
112 later, at your convenience.
113 You should make sure that the JPEG object is cleaned up (with jpeg_abort
114 or jpeg_destroy) at some point. }
118 procedure error_exit (cinfo
: j_common_ptr
);
120 { Always display the message }
121 cinfo
^.err
^.output_message(cinfo
);
123 { Let the memory manager delete any temp files before we die }
130 { Actual output of an error or trace message.
131 Applications may override this method to send JPEG messages somewhere
134 { Macros to simplify using the error and trace message stuff }
135 { The first parameter is either type of cinfo pointer }
137 { Fatal errors (print message and exit) }
138 procedure ERREXIT(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
);
140 cinfo
^.err
^.msg_code
:= ord(code
);
141 cinfo
^.err
^.error_exit(cinfo
);
144 procedure ERREXIT1(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
; p1
: uInt
);
146 cinfo
^.err
^.msg_code
:= ord(code
);
147 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
148 cinfo
^.err
^.error_exit (cinfo
);
151 procedure ERREXIT2(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
154 cinfo
^.err
^.msg_code
:= ord(code
);
155 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
156 cinfo
^.err
^.msg_parm
.i
[1] := p2
;
157 cinfo
^.err
^.error_exit (cinfo
);
160 procedure ERREXIT3(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
161 p1
: int
; p2
: int
; p3
: int
);
163 cinfo
^.err
^.msg_code
:= ord(code
);
164 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
165 cinfo
^.err
^.msg_parm
.i
[1] := p2
;
166 cinfo
^.err
^.msg_parm
.i
[2] := p3
;
167 cinfo
^.err
^.error_exit (cinfo
);
170 procedure ERREXIT4(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
171 p1
: int
; p2
: int
; p3
: int
; p4
: int
);
173 cinfo
^.err
^.msg_code
:= ord(code
);
174 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
175 cinfo
^.err
^.msg_parm
.i
[1] := p2
;
176 cinfo
^.err
^.msg_parm
.i
[2] := p3
;
177 cinfo
^.err
^.msg_parm
.i
[3] := p4
;
178 cinfo
^.err
^.error_exit (cinfo
);
181 procedure ERREXITS(cinfo
: j_common_ptr
;code
: J_MESSAGE_CODE
;
184 cinfo
^.err
^.msg_code
:= ord(code
);
185 cinfo
^.err
^.msg_parm
.s
:= str
; { string[JMSG_STR_PARM_MAX] }
186 cinfo
^.err
^.error_exit (cinfo
);
189 { Nonfatal errors (we can keep going, but the data is probably corrupt) }
191 procedure WARNMS(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
);
193 cinfo
^.err
^.msg_code
:= ord(code
);
194 cinfo
^.err
^.emit_message(cinfo
, -1);
197 procedure WARNMS1(cinfo
: j_common_ptr
;code
: J_MESSAGE_CODE
; p1
: int
);
199 cinfo
^.err
^.msg_code
:= ord(code
);
200 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
201 cinfo
^.err
^.emit_message (cinfo
, -1);
204 procedure WARNMS2(cinfo
: j_common_ptr
; code
: J_MESSAGE_CODE
;
207 cinfo
^.err
^.msg_code
:= ord(code
);
208 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
209 cinfo
^.err
^.msg_parm
.i
[1] := p2
;
210 cinfo
^.err
^.emit_message (cinfo
, -1);
213 { Informational/debugging messages }
214 procedure TRACEMS(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
);
216 cinfo
^.err
^.msg_code
:= ord(code
);
217 cinfo
^.err
^.emit_message(cinfo
, lvl
);
220 procedure TRACEMS1(cinfo
: j_common_ptr
; lvl
: int
;
221 code
: J_MESSAGE_CODE
; p1
: long
);
223 cinfo
^.err
^.msg_code
:= ord(code
);
224 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
225 cinfo
^.err
^.emit_message (cinfo
, lvl
);
228 procedure TRACEMS2(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
232 cinfo
^.err
^.msg_code
:= ord(code
);
233 cinfo
^.err
^.msg_parm
.i
[0] := p1
;
234 cinfo
^.err
^.msg_parm
.i
[1] := p2
;
235 cinfo
^.err
^.emit_message (cinfo
, lvl
);
238 procedure TRACEMS3(cinfo
: j_common_ptr
;
240 code
: J_MESSAGE_CODE
;
241 p1
: int
; p2
: int
; p3
: int
);
245 _mp
[0] := p1
; _mp
[1] := p2
; _mp
[2] := p3
;
246 cinfo
^.err
^.msg_parm
.i
:= _mp
;
247 cinfo
^.err
^.msg_code
:= ord(code
);
248 cinfo
^.err
^.emit_message (cinfo
, lvl
);
252 procedure TRACEMS4(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
253 p1
: int
; p2
: int
; p3
: int
; p4
: int
);
257 _mp
[0] := p1
; _mp
[1] := p2
; _mp
[2] := p3
; _mp
[3] := p4
;
258 cinfo
^.err
^.msg_parm
.i
:= _mp
;
259 cinfo
^.err
^.msg_code
:= ord(code
);
260 cinfo
^.err
^.emit_message (cinfo
, lvl
);
263 procedure TRACEMS5(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
264 p1
: int
; p2
: int
; p3
: int
; p4
: int
; p5
: int
);
268 _mp
:= @cinfo
^.err
^.msg_parm
.i
;
269 _mp
^[0] := p1
; _mp
^[1] := p2
; _mp
^[2] := p3
;
270 _mp
^[3] := p4
; _mp
^[5] := p5
;
271 cinfo
^.err
^.msg_code
:= ord(code
);
272 cinfo
^.err
^.emit_message (cinfo
, lvl
);
275 procedure TRACEMS8(cinfo
: j_common_ptr
; lvl
: int
; code
: J_MESSAGE_CODE
;
276 p1
: int
; p2
: int
; p3
: int
; p4
: int
;
277 p5
: int
; p6
: int
; p7
: int
; p8
: int
);
281 _mp
[0] := p1
; _mp
[1] := p2
; _mp
[2] := p3
; _mp
[3] := p4
;
282 _mp
[4] := p5
; _mp
[5] := p6
; _mp
[6] := p7
; _mp
[7] := p8
;
283 cinfo
^.err
^.msg_parm
.i
:= _mp
;
284 cinfo
^.err
^.msg_code
:= ord(code
);
285 cinfo
^.err
^.emit_message (cinfo
, lvl
);
288 procedure TRACEMSS(cinfo
: j_common_ptr
; lvl
: int
;
289 code
: J_MESSAGE_CODE
; str
: AnsiString);
291 cinfo
^.err
^.msg_code
:= ord(code
);
292 cinfo
^.err
^.msg_parm
.s
:= str
; { string JMSG_STR_PARM_MAX }
293 cinfo
^.err
^.emit_message (cinfo
, lvl
);
297 procedure output_message (cinfo
: j_common_ptr
);
299 buffer
: AnsiString; {[JMSG_LENGTH_MAX];}
301 { Create the message }
302 cinfo
^.err
^.format_message (cinfo
, buffer
);
304 { Send it to stderr, adding a newline }
305 WriteLn(output
, buffer
);
310 { Decide whether to emit a trace or warning message.
312 -1: recoverable corrupt-data warning, may want to abort.
313 0: important advisory messages (always display to user).
314 1: first level of tracing detail.
315 2,3,...: successively more detailed tracing messages.
316 An application might override this method if it wanted to abort on warnings
317 or change the policy about which messages to display. }
321 procedure emit_message (cinfo
: j_common_ptr
; msg_level
: int
);
323 err
: jpeg_error_mgr_ptr
;
326 if (msg_level
< 0) then
328 { It's a warning message. Since corrupt files may generate many warnings,
329 the policy implemented here is to show only the first warning,
330 unless trace_level >= 3. }
332 if (err
^.num_warnings
= 0) or (err
^.trace_level
>= 3) then
333 err
^.output_message(cinfo
);
334 { Always count warnings in num_warnings. }
335 Inc( err
^.num_warnings
);
339 { It's a trace message. Show it if trace_level >= msg_level. }
340 if (err
^.trace_level
>= msg_level
) then
341 err
^.output_message (cinfo
);
346 { Format a message string for the most recent JPEG error or message.
347 The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
348 characters. Note that no '\n' character is added to the string.
349 Few applications should need to override this method. }
353 procedure format_message (cinfo
: j_common_ptr
; var buffer
: AnsiString);
355 err
: jpeg_error_mgr_ptr
;
356 msg_code
: J_MESSAGE_CODE
;
357 msgtext
: AnsiString;
361 msg_code
:= J_MESSAGE_CODE(err
^.msg_code
);
364 { Look up message string in proper table }
365 if (msg_code
> JMSG_NOMESSAGE
)
366 and (msg_code
<= J_MESSAGE_CODE(err
^.last_jpeg_message
)) then
368 msgtext
:= err
^.jpeg_message_table
^[msg_code
];
371 if (err
^.addon_message_table
<> NIL) and
372 (msg_code
>= err
^.first_addon_message
) and
373 (msg_code
<= err
^.last_addon_message
) then
375 msgtext
:= err
^.addon_message_table
^[J_MESSAGE_CODE
376 (ord(msg_code
) - ord(err
^.first_addon_message
))];
379 { Defend against bogus message number }
380 if (msgtext
= '') then
382 err
^.msg_parm
.i
[0] := int(msg_code
);
383 msgtext
:= err
^.jpeg_message_table
^[JMSG_NOMESSAGE
];
386 { Check for string parameter, as indicated by %s in the message text }
387 isstring
:= Pos('%s', msgtext
) > 0;
389 { Format the message into the passed buffer }
391 buffer
:= Concat(msgtext
, err
^.msg_parm
.s
)
395 FormatStr(buffer
, msgtext
, err
^.msg_parm
.i
);
400 buffer
:= Format(msgtext
, [
401 err
^.msg_parm
.i
[0], err
^.msg_parm
.i
[1],
402 err
^.msg_parm
.i
[2], err
^.msg_parm
.i
[3],
403 err
^.msg_parm
.i
[4], err
^.msg_parm
.i
[5],
404 err
^.msg_parm
.i
[6], err
^.msg_parm
.i
[7] ]);
412 { Reset error state variables at start of a new image.
413 This is called during compression startup to reset trace/error
414 processing to default state, without losing any application-specific
415 method pointers. An application might possibly want to override
416 this method if it has additional error processing state. }
420 procedure reset_error_mgr (cinfo
: j_common_ptr
);
422 cinfo
^.err
^.num_warnings
:= 0;
423 { trace_level is not reset since it is an application-supplied parameter }
424 cinfo
^.err
^.msg_code
:= 0; { may be useful as a flag for "no error" }
428 { Fill in the standard error-handling methods in a jpeg_error_mgr object.
430 cinfo : jpeg_compress_struct;
431 err : jpeg_error_mgr;
433 cinfo.err := jpeg_std_error(@err);
434 after which the application may override some of the methods. }
438 function jpeg_std_error (var err
: jpeg_error_mgr
) : jpeg_error_mgr_ptr
;
440 err
.error_exit
:= error_exit
;
441 err
.emit_message
:= emit_message
;
442 err
.output_message
:= output_message
;
443 err
.format_message
:= format_message
;
444 err
.reset_error_mgr
:= reset_error_mgr
;
446 err
.trace_level
:= 0; { default := no tracing }
447 err
.num_warnings
:= 0; { no warnings emitted yet }
448 err
.msg_code
:= 0; { may be useful as a flag for "no error" }
450 { Initialize message table pointers }
451 err
.jpeg_message_table
:= @jpeg_std_message_table
;
452 err
.last_jpeg_message
:= pred(JMSG_LASTMSGCODE
);
454 err
.addon_message_table
:= NIL;
455 err
.first_addon_message
:= JMSG_NOMESSAGE
; { for safety }
456 err
.last_addon_message
:= JMSG_NOMESSAGE
;
458 jpeg_std_error
:= @err
;