error.cc (3179B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "lib/jpegli/error.h" 7 8 #include <setjmp.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <string> 13 14 #include "lib/jpegli/common.h" 15 16 namespace jpegli { 17 18 const char* const kErrorMessageTable[] = { 19 "Message codes are not supported, error message is in msg_parm.s string", 20 }; 21 22 bool FormatString(char* buffer, const char* format, ...) { 23 va_list args; 24 va_start(args, format); 25 vsnprintf(buffer, JMSG_STR_PARM_MAX, format, args); 26 va_end(args); 27 return false; 28 } 29 30 void ExitWithAbort(j_common_ptr cinfo) { 31 (*cinfo->err->output_message)(cinfo); 32 jpegli_destroy(cinfo); 33 exit(EXIT_FAILURE); 34 } 35 36 void EmitMessage(j_common_ptr cinfo, int msg_level) { 37 if (msg_level < 0) { 38 if (cinfo->err->num_warnings <= 5 || cinfo->err->trace_level >= 3) { 39 (*cinfo->err->output_message)(cinfo); 40 } 41 ++cinfo->err->num_warnings; 42 } else if (cinfo->err->trace_level >= msg_level) { 43 (*cinfo->err->output_message)(cinfo); 44 } 45 } 46 47 void OutputMessage(j_common_ptr cinfo) { 48 char buffer[JMSG_LENGTH_MAX]; 49 (*cinfo->err->format_message)(cinfo, buffer); 50 fprintf(stderr, "%s\n", buffer); 51 } 52 53 void FormatMessage(j_common_ptr cinfo, char* buffer) { 54 jpeg_error_mgr* err = cinfo->err; 55 int code = err->msg_code; 56 if (code == 0) { 57 memcpy(buffer, cinfo->err->msg_parm.s, JMSG_STR_PARM_MAX); 58 } else if (err->addon_message_table != nullptr && 59 code >= err->first_addon_message && 60 code <= err->last_addon_message) { 61 std::string msg(err->addon_message_table[code - err->first_addon_message]); 62 if (msg.find("%s") != std::string::npos) { 63 snprintf(buffer, JMSG_LENGTH_MAX, msg.data(), err->msg_parm.s); 64 } else { 65 snprintf(buffer, JMSG_LENGTH_MAX, msg.data(), err->msg_parm.i[0], 66 err->msg_parm.i[1], err->msg_parm.i[2], err->msg_parm.i[3], 67 err->msg_parm.i[4], err->msg_parm.i[5], err->msg_parm.i[6], 68 err->msg_parm.i[7]); 69 } 70 } else { 71 snprintf(buffer, JMSG_LENGTH_MAX, "%s", kErrorMessageTable[0]); 72 } 73 } 74 75 void ResetErrorManager(j_common_ptr cinfo) { 76 memset(cinfo->err->msg_parm.s, 0, JMSG_STR_PARM_MAX); 77 cinfo->err->msg_code = 0; 78 cinfo->err->num_warnings = 0; 79 } 80 81 } // namespace jpegli 82 83 struct jpeg_error_mgr* jpegli_std_error(struct jpeg_error_mgr* err) { 84 err->error_exit = jpegli::ExitWithAbort; 85 err->emit_message = jpegli::EmitMessage; 86 err->output_message = jpegli::OutputMessage; 87 err->format_message = jpegli::FormatMessage; 88 err->reset_error_mgr = jpegli::ResetErrorManager; 89 memset(err->msg_parm.s, 0, JMSG_STR_PARM_MAX); 90 err->trace_level = 0; 91 err->num_warnings = 0; 92 // We don't support message codes and message table, but we define one here 93 // in case the application has a custom format_message and tries to access 94 // these fields there. 95 err->msg_code = 0; 96 err->jpeg_message_table = jpegli::kErrorMessageTable; 97 err->last_jpeg_message = 0; 98 err->addon_message_table = nullptr; 99 err->first_addon_message = 0; 100 err->last_addon_message = 0; 101 return err; 102 }