Wed, 05 Mar 2003 01:58:31 +0000
*** empty log message ***
bitblt_g4.c | file | annotate | diff | revisions | |
pdf_g4.c | file | annotate | diff | revisions |
1.1 --- a/bitblt_g4.c Sun Feb 23 17:40:41 2003 +0000 1.2 +++ b/bitblt_g4.c Wed Mar 05 01:58:31 2003 +0000 1.3 @@ -4,7 +4,7 @@ 1.4 * will be compressed using ITU-T T.6 (G4) fax encoding. 1.5 * 1.6 * PDF routines 1.7 - * $Id: bitblt_g4.c,v 1.6 2003/02/21 02:49:11 eric Exp $ 1.8 + * $Id: bitblt_g4.c,v 1.7 2003/03/04 17:58:31 eric Exp $ 1.9 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 1.10 * 1.11 * This program is free software; you can redistribute it and/or modify 1.12 @@ -38,6 +38,9 @@ 1.13 #include "pdf_private.h" 1.14 1.15 1.16 +#include "pdf_g4_tables.h" 1.17 + 1.18 + 1.19 #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 1.20 1.21 1.22 @@ -92,6 +95,103 @@ 1.23 } 1.24 1.25 1.26 +static void pdf_g4_encode_horizontal_run (pdf_file_handle pdf_file, 1.27 + struct pdf_obj *stream, 1.28 + bool black, 1.29 + uint32_t run_length) 1.30 +{ 1.31 + uint32_t i; 1.32 + 1.33 + while (run_length >= 2560) 1.34 + { 1.35 + pdf_stream_write_bits (pdf_file, stream, 12, 0x01f); 1.36 + run_length -= 2560; 1.37 + } 1.38 + 1.39 + if (run_length >= 1792) 1.40 + { 1.41 + i = (run_length - 1792) >> 6; 1.42 + pdf_stream_write_bits (pdf_file, stream, 1.43 + g4_long_makeup_code [i].count, 1.44 + g4_long_makeup_code [i].bits); 1.45 + run_length -= (1792 + (i << 6)); 1.46 + } 1.47 + else if (run_length >= 64) 1.48 + { 1.49 + i = (run_length >> 6) - 1; 1.50 + pdf_stream_write_bits (pdf_file, stream, 1.51 + g4_makeup_code [black] [i].count, 1.52 + g4_makeup_code [black] [i].bits); 1.53 + run_length -= (i + 1) << 6; 1.54 + } 1.55 + 1.56 + pdf_stream_write_bits (pdf_file, stream, 1.57 + g4_h_code [black] [run_length].count, 1.58 + g4_h_code [black] [run_length].bits); 1.59 +} 1.60 + 1.61 + 1.62 +uint32_t find_transition (uint8_t *data, 1.63 + uint32_t pos, 1.64 + uint32_t width) 1.65 +{ 1.66 + if (! data) 1.67 + return (width); 1.68 + return (0); /* $$$ */ 1.69 +} 1.70 + 1.71 + 1.72 +static void pdf_g4_encode_row (pdf_file_handle pdf_file, 1.73 + struct pdf_obj *stream, 1.74 + uint32_t width, 1.75 + uint8_t *ref, 1.76 + uint8_t *row) 1.77 +{ 1.78 + int a0, a1, a2; 1.79 + int b1, b2; 1.80 + 1.81 + a0 = -1; 1.82 + 1.83 + while (a0 < width) 1.84 + { 1.85 + /* find a1, a2 */ 1.86 + a1 = find_transition (row, a0, width); 1.87 + a2 = find_transition (row, a1, width); 1.88 + 1.89 + /* find b1, b2 */ 1.90 + b1 = find_transition (ref, a0, width); 1.91 + if (0) /* $$$ b1 color = a0 color */ 1.92 + b1 = find_transition (ref, b1, width); 1.93 + b2 = find_transition (ref, b2, width); 1.94 + 1.95 + if (b2 < a1) 1.96 + { 1.97 + /* pass mode - 0001 */ 1.98 + pdf_stream_write_bits (pdf_file, stream, 4, 0x1); 1.99 + a0 = b2; 1.100 + } 1.101 + else if (abs (a1 - b1) <= 3) 1.102 + { 1.103 + /* vertical mode */ 1.104 + pdf_stream_write_bits (pdf_file, stream, 1.105 + g4_vert_code [3 + a1 - b1].count, 1.106 + g4_vert_code [3 + a1 - b1].bits); 1.107 + a0 = a1; 1.108 + } 1.109 + else 1.110 + { 1.111 + /* horizontal mode - 001 */ 1.112 + pdf_stream_write_bits (pdf_file, stream, 3, 0x1); 1.113 + pdf_g4_encode_horizontal_run (pdf_file, stream, 1.114 + 0 /* $$$ color (a0) */, a1 - a0); 1.115 + pdf_g4_encode_horizontal_run (pdf_file, stream, 1.116 + 1 /* $$$ color (a1) */, a2 - a1); 1.117 + a0 = a2; 1.118 + } 1.119 + } 1.120 +} 1.121 + 1.122 + 1.123 void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file, 1.124 struct pdf_obj *stream, 1.125 void *app_data) 1.126 @@ -100,46 +200,25 @@ 1.127 1.128 uint32_t row; 1.129 1.130 - /* reference (previous) row */ 1.131 - uint32_t *ref_runs = pdf_calloc (image->Columns, sizeof (uint32_t)); 1.132 - uint32_t ref_run_count; 1.133 - 1.134 - /* row being converted */ 1.135 - uint32_t *row_runs = pdf_calloc (image->Columns, sizeof (uint32_t)); 1.136 - uint32_t row_run_count; 1.137 - 1.138 - /* initialize reference row - all white */ 1.139 - ref_runs [0] = image->Columns; 1.140 - ref_run_count = 0; 1.141 + word_type *ref_line = NULL; /* reference (previous) row */ 1.142 + word_type *line = image->bitmap->bits; 1.143 1.144 for (row = image->bitmap->rect.min.y; 1.145 row < image->bitmap->rect.max.y; 1.146 row++) 1.147 { 1.148 - row_run_count = get_row_run_lengths (image->bitmap, 1.149 - row, 1.150 - image->bitmap->rect.min.x, 1.151 - image->bitmap->rect.max.x - 1, 1.152 - image->Columns, /* max_runs */ 1.153 - row_runs); 1.154 - pdf_assert (row_run_count > 0); 1.155 - 1.156 - /* $$$ G4 encode the runs here */ 1.157 - 1.158 - /* pdf_stream_write_data (pdf_file, stream, image->data, image->len); */ 1.159 - 1.160 - SWAP (uint32_t *, row_runs, ref_runs); 1.161 - ref_run_count = row_run_count; 1.162 + pdf_g4_encode_row (pdf_file, stream, image->Columns, 1.163 + (uint8_t *) ref_line, 1.164 + (uint8_t *) line); 1.165 + ref_line = line; 1.166 + line += image->bitmap->row_words; 1.167 } 1.168 1.169 1.170 - /* $$$ generate and write EOFB code */ 1.171 + /* write EOFB code */ 1.172 pdf_stream_write_bits (pdf_file, stream, 24, 0x001001); 1.173 1.174 pdf_stream_flush_bits (pdf_file, stream); 1.175 - 1.176 - free (ref_runs); 1.177 - free (row_runs); 1.178 } 1.179 1.180
2.1 --- a/pdf_g4.c Sun Feb 23 17:40:41 2003 +0000 2.2 +++ b/pdf_g4.c Wed Mar 05 01:58:31 2003 +0000 2.3 @@ -4,7 +4,7 @@ 2.4 * will be compressed using ITU-T T.6 (G4) fax encoding. 2.5 * 2.6 * PDF routines 2.7 - * $Id: pdf_g4.c,v 1.6 2003/02/21 02:49:11 eric Exp $ 2.8 + * $Id: pdf_g4.c,v 1.7 2003/03/04 17:58:31 eric Exp $ 2.9 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 2.10 * 2.11 * This program is free software; you can redistribute it and/or modify 2.12 @@ -38,6 +38,9 @@ 2.13 #include "pdf_private.h" 2.14 2.15 2.16 +#include "pdf_g4_tables.h" 2.17 + 2.18 + 2.19 #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 2.20 2.21 2.22 @@ -92,6 +95,103 @@ 2.23 } 2.24 2.25 2.26 +static void pdf_g4_encode_horizontal_run (pdf_file_handle pdf_file, 2.27 + struct pdf_obj *stream, 2.28 + bool black, 2.29 + uint32_t run_length) 2.30 +{ 2.31 + uint32_t i; 2.32 + 2.33 + while (run_length >= 2560) 2.34 + { 2.35 + pdf_stream_write_bits (pdf_file, stream, 12, 0x01f); 2.36 + run_length -= 2560; 2.37 + } 2.38 + 2.39 + if (run_length >= 1792) 2.40 + { 2.41 + i = (run_length - 1792) >> 6; 2.42 + pdf_stream_write_bits (pdf_file, stream, 2.43 + g4_long_makeup_code [i].count, 2.44 + g4_long_makeup_code [i].bits); 2.45 + run_length -= (1792 + (i << 6)); 2.46 + } 2.47 + else if (run_length >= 64) 2.48 + { 2.49 + i = (run_length >> 6) - 1; 2.50 + pdf_stream_write_bits (pdf_file, stream, 2.51 + g4_makeup_code [black] [i].count, 2.52 + g4_makeup_code [black] [i].bits); 2.53 + run_length -= (i + 1) << 6; 2.54 + } 2.55 + 2.56 + pdf_stream_write_bits (pdf_file, stream, 2.57 + g4_h_code [black] [run_length].count, 2.58 + g4_h_code [black] [run_length].bits); 2.59 +} 2.60 + 2.61 + 2.62 +uint32_t find_transition (uint8_t *data, 2.63 + uint32_t pos, 2.64 + uint32_t width) 2.65 +{ 2.66 + if (! data) 2.67 + return (width); 2.68 + return (0); /* $$$ */ 2.69 +} 2.70 + 2.71 + 2.72 +static void pdf_g4_encode_row (pdf_file_handle pdf_file, 2.73 + struct pdf_obj *stream, 2.74 + uint32_t width, 2.75 + uint8_t *ref, 2.76 + uint8_t *row) 2.77 +{ 2.78 + int a0, a1, a2; 2.79 + int b1, b2; 2.80 + 2.81 + a0 = -1; 2.82 + 2.83 + while (a0 < width) 2.84 + { 2.85 + /* find a1, a2 */ 2.86 + a1 = find_transition (row, a0, width); 2.87 + a2 = find_transition (row, a1, width); 2.88 + 2.89 + /* find b1, b2 */ 2.90 + b1 = find_transition (ref, a0, width); 2.91 + if (0) /* $$$ b1 color = a0 color */ 2.92 + b1 = find_transition (ref, b1, width); 2.93 + b2 = find_transition (ref, b2, width); 2.94 + 2.95 + if (b2 < a1) 2.96 + { 2.97 + /* pass mode - 0001 */ 2.98 + pdf_stream_write_bits (pdf_file, stream, 4, 0x1); 2.99 + a0 = b2; 2.100 + } 2.101 + else if (abs (a1 - b1) <= 3) 2.102 + { 2.103 + /* vertical mode */ 2.104 + pdf_stream_write_bits (pdf_file, stream, 2.105 + g4_vert_code [3 + a1 - b1].count, 2.106 + g4_vert_code [3 + a1 - b1].bits); 2.107 + a0 = a1; 2.108 + } 2.109 + else 2.110 + { 2.111 + /* horizontal mode - 001 */ 2.112 + pdf_stream_write_bits (pdf_file, stream, 3, 0x1); 2.113 + pdf_g4_encode_horizontal_run (pdf_file, stream, 2.114 + 0 /* $$$ color (a0) */, a1 - a0); 2.115 + pdf_g4_encode_horizontal_run (pdf_file, stream, 2.116 + 1 /* $$$ color (a1) */, a2 - a1); 2.117 + a0 = a2; 2.118 + } 2.119 + } 2.120 +} 2.121 + 2.122 + 2.123 void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file, 2.124 struct pdf_obj *stream, 2.125 void *app_data) 2.126 @@ -100,46 +200,25 @@ 2.127 2.128 uint32_t row; 2.129 2.130 - /* reference (previous) row */ 2.131 - uint32_t *ref_runs = pdf_calloc (image->Columns, sizeof (uint32_t)); 2.132 - uint32_t ref_run_count; 2.133 - 2.134 - /* row being converted */ 2.135 - uint32_t *row_runs = pdf_calloc (image->Columns, sizeof (uint32_t)); 2.136 - uint32_t row_run_count; 2.137 - 2.138 - /* initialize reference row - all white */ 2.139 - ref_runs [0] = image->Columns; 2.140 - ref_run_count = 0; 2.141 + word_type *ref_line = NULL; /* reference (previous) row */ 2.142 + word_type *line = image->bitmap->bits; 2.143 2.144 for (row = image->bitmap->rect.min.y; 2.145 row < image->bitmap->rect.max.y; 2.146 row++) 2.147 { 2.148 - row_run_count = get_row_run_lengths (image->bitmap, 2.149 - row, 2.150 - image->bitmap->rect.min.x, 2.151 - image->bitmap->rect.max.x - 1, 2.152 - image->Columns, /* max_runs */ 2.153 - row_runs); 2.154 - pdf_assert (row_run_count > 0); 2.155 - 2.156 - /* $$$ G4 encode the runs here */ 2.157 - 2.158 - /* pdf_stream_write_data (pdf_file, stream, image->data, image->len); */ 2.159 - 2.160 - SWAP (uint32_t *, row_runs, ref_runs); 2.161 - ref_run_count = row_run_count; 2.162 + pdf_g4_encode_row (pdf_file, stream, image->Columns, 2.163 + (uint8_t *) ref_line, 2.164 + (uint8_t *) line); 2.165 + ref_line = line; 2.166 + line += image->bitmap->row_words; 2.167 } 2.168 2.169 2.170 - /* $$$ generate and write EOFB code */ 2.171 + /* write EOFB code */ 2.172 pdf_stream_write_bits (pdf_file, stream, 24, 0x001001); 2.173 2.174 pdf_stream_flush_bits (pdf_file, stream); 2.175 - 2.176 - free (ref_runs); 2.177 - free (row_runs); 2.178 } 2.179 2.180