summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2018-11-13 04:18:21 +0100
committerChris Liddell <chris.liddell@artifex.com>2018-11-16 15:03:56 +0000
commita92e38603902b22c5b20fecefa5da3d2a233516c (patch)
tree959416763bd6ba480510437125ed1ca8701db79c
parent3bb28e08002ef4a90bddb05aa6cd06a256153663 (diff)
downloadghostpdl-a92e38603902b22c5b20fecefa5da3d2a233516c.tar.gz
jbig2dec: Only print repeated error/warning messages once.
-rw-r--r--base/sjbig2.c86
-rw-r--r--base/sjbig2.h4
-rw-r--r--jbig2dec/jbig2dec.c58
3 files changed, 142 insertions, 6 deletions
diff --git a/base/sjbig2.c b/base/sjbig2.c
index cf308869f..89b26b414 100644
--- a/base/sjbig2.c
+++ b/base/sjbig2.c
@@ -66,10 +66,61 @@ s_jbig2decode_error(void *callback_data, const char *msg, Jbig2Severity severity
if (error_data)
{
- if (severity == JBIG2_SEVERITY_FATAL || severity == JBIG2_SEVERITY_WARNING) {
- dmlprintf3(error_data->memory, "jbig2dec %s %s %s\n", type, msg, segment);
- } else {
- if_debug3m('w', error_data->memory, "[w] jbig2dec %s %s %s\n", type, msg, segment);
+ char *message;
+ int len;
+
+ len = snprintf(NULL, 0, "jbig2dec %s %s %s", type, msg, segment);
+ if (len < 0)
+ return;
+
+ message = (char *)gs_alloc_bytes(error_data->memory, len + 1, "sjbig2decode_error(message)");
+ if (message == NULL)
+ return;
+
+ len = snprintf(message, len + 1, "jbig2dec %s %s %s", type, msg, segment);
+ if (len < 0)
+ {
+ gs_free_object(error_data->memory, message, "s_jbig2decode_error(message)");
+ return;
+ }
+
+ if (error_data->last_message != NULL && strcmp(message, error_data->last_message)) {
+ if (error_data->repeats > 1)
+ {
+ if (error_data->severity == JBIG2_SEVERITY_FATAL || error_data->severity == JBIG2_SEVERITY_WARNING) {
+ dmlprintf1(error_data->memory, "jbig2dec last message repeated %ld times\n", error_data->repeats);
+ } else {
+ if_debug1m('w', error_data->memory, "[w] jbig2dec last message repeated %ld times\n", error_data->repeats);
+ }
+ }
+ gs_free_object(error_data->memory, error_data->last_message, "s_jbig2decode_error(last_message)");
+ error_data->last_message = message;
+ error_data->severity = severity;
+ error_data->type = type;
+ error_data->repeats = 0;
+ }
+ else if (error_data->last_message != NULL) {
+ error_data->repeats++;
+ if (error_data->repeats % 1000000 == 0)
+ {
+ if (error_data->severity == JBIG2_SEVERITY_FATAL || error_data->severity == JBIG2_SEVERITY_WARNING) {
+ dmlprintf1(error_data->memory, "jbig2dec last message repeated %ld times so far\n", error_data->repeats);
+ } else {
+ if_debug1m('w', error_data->memory, "[w] jbig2dec last message repeated %ld times so far\n", error_data->repeats);
+ }
+ }
+ gs_free_object(error_data->memory, message, "s_jbig2decode_error(message)");
+ }
+ else if (error_data->last_message == NULL) {
+ if (severity == JBIG2_SEVERITY_FATAL || severity == JBIG2_SEVERITY_WARNING) {
+ dmlprintf1(error_data->memory, "%s\n", message);
+ } else {
+ if_debug1m('w', error_data->memory, "[w] %s\n", message);
+ }
+ error_data->last_message = message;
+ error_data->severity = severity;
+ error_data->type = type;
+ error_data->repeats = 0;
}
}
else
@@ -86,6 +137,29 @@ s_jbig2decode_error(void *callback_data, const char *msg, Jbig2Severity severity
}
}
+static void
+s_jbig2decode_flush_errors(void *callback_data)
+{
+ s_jbig2_callback_data_t *error_data = (s_jbig2_callback_data_t *)callback_data;
+
+ if (error_data == NULL)
+ return;
+
+ if (error_data->last_message != NULL) {
+ if (error_data->repeats > 1)
+ {
+ if (error_data->severity == JBIG2_SEVERITY_FATAL || error_data->severity == JBIG2_SEVERITY_WARNING) {
+ dmlprintf1(error_data->memory, "jbig2dec last message repeated %ld times\n", error_data->repeats);
+ } else {
+ if_debug1m('w', error_data->memory, "[w] jbig2dec last message repeated %ld times\n", error_data->repeats);
+ }
+ }
+ gs_free_object(error_data->memory, error_data->last_message, "s_jbig2decode_error(last_message)");
+ error_data->last_message = NULL;
+ error_data->repeats = 0;
+ }
+}
+
/* invert the bits in a buffer */
/* jbig2 and postscript have different senses of what pixel
value is black, so we must invert the image */
@@ -171,6 +245,8 @@ s_jbig2decode_init(stream_state * ss)
if (state->callback_data) {
state->callback_data->memory = ss->memory->non_gc_memory;
state->callback_data->error = 0;
+ state->callback_data->last_message = NULL;
+ state->callback_data->repeats = 0;
/* initialize the decoder with the parsed global context if any */
state->decode_ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED,
global_ctx, s_jbig2decode_error, state->callback_data);
@@ -249,11 +325,13 @@ s_jbig2decode_release(stream_state *ss)
if (state->decode_ctx) {
if (state->image) jbig2_release_page(state->decode_ctx, state->image);
state->image = NULL;
+ s_jbig2decode_flush_errors(state->callback_data);
jbig2_ctx_free(state->decode_ctx);
state->decode_ctx = NULL;
}
if (state->callback_data) {
gs_memory_t *mem = state->callback_data->memory;
+ gs_free_object(state->callback_data->memory, state->callback_data->last_message, "s_jbig2decode_release(message)");
gs_free_object(mem, state->callback_data, "s_jbig2decode_release(callback_data)");
state->callback_data = NULL;
}
diff --git a/base/sjbig2.h b/base/sjbig2.h
index f94f4b0ec..50289ce94 100644
--- a/base/sjbig2.h
+++ b/base/sjbig2.h
@@ -28,6 +28,10 @@ typedef struct s_jbig2_callback_data_s
{
gs_memory_t *memory;
int error;
+ char *last_message;
+ Jbig2Severity severity;
+ const char *type;
+ long repeats;
} s_jbig2_callback_data_t;
/* See zfjbig2.c for details. */
diff --git a/jbig2dec/jbig2dec.c b/jbig2dec/jbig2dec.c
index cc6358d49..1a455c01f 100644
--- a/jbig2dec/jbig2dec.c
+++ b/jbig2dec/jbig2dec.c
@@ -66,6 +66,10 @@ typedef struct {
SHA1_CTX *hash_ctx;
char *output_filename;
jbig2dec_format output_format;
+ char *last_message;
+ Jbig2Severity severity;
+ char *type;
+ long repeats;
} jbig2dec_params_t;
static int print_version(void);
@@ -248,9 +252,11 @@ print_usage(void)
static void
error_callback(void *error_callback_data, const char *buf, Jbig2Severity severity, int32_t seg_idx)
{
- const jbig2dec_params_t *params = (jbig2dec_params_t *) error_callback_data;
+ jbig2dec_params_t *params = (jbig2dec_params_t *) error_callback_data;
char *type;
char segment[22];
+ int len;
+ char *message;
switch (severity) {
case JBIG2_SEVERITY_DEBUG:
@@ -280,7 +286,52 @@ error_callback(void *error_callback_data, const char *buf, Jbig2Severity severit
else
snprintf(segment, sizeof(segment), "(segment 0x%02x)", seg_idx);
- fprintf(stderr, "jbig2dec %s %s %s\n", type, buf, segment);
+ len = snprintf(NULL, 0, "jbig2dec %s %s %s", type, buf, segment);
+ if (len < 0) {
+ return;
+ }
+
+ message = malloc(len + 1);
+ if (message == NULL) {
+ return;
+ }
+
+ len = snprintf(message, len + 1, "jbig2dec %s %s %s", type, buf, segment);
+ if (len < 0)
+ {
+ free(message);
+ return;
+ }
+
+ if (params->last_message != NULL && strcmp(message, params->last_message)) {
+ if (params->repeats > 1)
+ fprintf(stderr, "jbig2dec %s last message repeated %ld times\n", params->type, params->repeats);
+ fprintf(stderr, "%s\n", message);
+ free(params->last_message);
+ params->last_message = message;
+ params->severity = severity;
+ params->type = type;
+ params->repeats = 0;
+ } else if (params->last_message != NULL) {
+ params->repeats++;
+ if (params->repeats % 1000000 == 0)
+ fprintf(stderr, "jbig2dec %s last message repeated %ld times so far\n", params->type, params->repeats);
+ free(message);
+ } else if (params->last_message == NULL) {
+ fprintf(stderr, "%s\n", message);
+ params->last_message = message;
+ params->severity = severity;
+ params->type = type;
+ params->repeats = 0;
+ }
+}
+
+static void
+flush_errors(jbig2dec_params_t *params)
+{
+ if (params->repeats > 1) {
+ fprintf(stderr, "jbig2dec last message repeated %ld times\n", params->repeats);
+ }
}
static char *
@@ -387,6 +438,8 @@ main(int argc, char **argv)
params.output_filename = NULL;
params.output_format = jbig2dec_format_none;
params.embedded = 0;
+ params.last_message = NULL;
+ params.repeats = 0;
filearg = parse_options(argc, argv, &params);
@@ -541,6 +594,7 @@ main(int argc, char **argv)
result = 0;
cleanup:
+ flush_errors(&params);
jbig2_ctx_free(ctx);
if (params.output_filename)
free(params.output_filename);