1/* 2 * Copyright 2007, J��r��me Duval. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "HPGSTranslator.h" 8#include "ConfigView.h" 9#include "ReadHelper.h" 10 11#include "hpgsimage.h" 12 13#include <Catalog.h> 14#include <Messenger.h> 15#include <TranslatorRoster.h> 16 17#include <stdlib.h> 18#include <stdio.h> 19#include <string.h> 20 21#undef B_TRANSLATION_CONTEXT 22#define B_TRANSLATION_CONTEXT "HPGSTranslator" 23 24 25typedef struct my_hpgs_png_image_st { 26 hpgs_png_image image; 27 BPositionIO *target; 28} my_hpgs_png_image; 29 30 31int 32my_pim_write(hpgs_image *_this, const char *filename) 33{ 34 BPositionIO* target = ((my_hpgs_png_image *)_this)->target; 35 unsigned char *row; 36 int stride, depth; 37 _this->vtable->get_data(_this, &row, &stride, &depth); 38 for (int i = 0; i< _this->height; ++i) { 39 ssize_t bytesWritten = target->Write(row, stride); 40 if (bytesWritten < B_OK) 41 return bytesWritten; 42 row += stride; 43 } 44 45 return 0; 46} 47 48 49// The input formats that this translator supports. 50static const translation_format sInputFormats[] = { 51 { 52 HPGS_IMAGE_FORMAT, 53 B_TRANSLATOR_BITMAP, 54 HPGS_IN_QUALITY, 55 HPGS_IN_CAPABILITY, 56 "vector/x-hpgl2", 57 "HP-GL/2" 58 }, 59}; 60 61// The output formats that this translator supports. 62static const translation_format sOutputFormats[] = { 63 { 64 B_TRANSLATOR_BITMAP, 65 B_TRANSLATOR_BITMAP, 66 BITS_OUT_QUALITY, 67 BITS_OUT_CAPABILITY, 68 "image/x-be-bitmap", 69 "Be Bitmap Format (HPGSTranslator)" 70 }, 71}; 72 73// Default settings for the Translator 74static const TranSetting sDefaultSettings[] = { 75 {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, 76 {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false} 77}; 78 79const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); 80const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format); 81const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting); 82 83 84// #pragma mark - 85 86 87HPGSTranslator::HPGSTranslator() 88 : BaseTranslator(B_TRANSLATE("HPGS images"), 89 B_TRANSLATE("HPGS image translator"), 90 HPGS_TRANSLATOR_VERSION, 91 sInputFormats, kNumInputFormats, 92 sOutputFormats, kNumOutputFormats, 93 "HPGSTranslator_Settings", 94 sDefaultSettings, kNumDefaultSettings, 95 B_TRANSLATOR_BITMAP, HPGS_IMAGE_FORMAT) 96{ 97 hpgs_init("/usr/local"); 98} 99 100 101HPGSTranslator::~HPGSTranslator() 102{ 103 hpgs_cleanup(); 104} 105 106 107status_t 108HPGSTranslator::DerivedIdentify(BPositionIO *stream, 109 const translation_format *format, BMessage *settings, 110 translator_info *info, uint32 outType) 111{ 112 if (!outType) 113 outType = B_TRANSLATOR_BITMAP; 114 if (outType != B_TRANSLATOR_BITMAP) 115 return B_NO_TRANSLATOR; 116 117 hpgs_istream *istream = hpgs_new_wrapper_istream(stream); 118 119 status_t err = B_OK; 120 int verbosity = 1; 121 hpgs_bool multipage = HPGS_FALSE; 122 hpgs_bool ignore_ps = HPGS_FALSE; 123 hpgs_bool do_linewidth = HPGS_TRUE; 124 hpgs_device *size_dev = (hpgs_device *)hpgs_new_plotsize_device(ignore_ps, 125 do_linewidth); 126 hpgs_reader *reader = hpgs_new_reader(istream, size_dev, multipage, 127 verbosity); 128 if (hpgs_read(reader, HPGS_FALSE) == B_OK) { 129 info->type = HPGS_IMAGE_FORMAT; 130 info->group = B_TRANSLATOR_BITMAP; 131 info->quality = HPGS_IN_QUALITY; 132 info->capability = HPGS_IN_CAPABILITY; 133 snprintf(info->name, sizeof(info->name), B_TRANSLATE("HPGS image")); 134 strcpy(info->MIME, "vector/x-hpgl2"); 135 } else 136 err = B_NO_TRANSLATOR; 137 138 free(reader); 139 free(size_dev); 140 hpgs_free_wrapper_istream(istream); 141 142 return err; 143} 144 145 146status_t 147HPGSTranslator::DerivedTranslate(BPositionIO* source, 148 const translator_info* info, BMessage* settings, 149 uint32 outType, BPositionIO* target, int32 baseType) 150{ 151 if (!outType) 152 outType = B_TRANSLATOR_BITMAP; 153 if (outType != B_TRANSLATOR_BITMAP || baseType != 0) 154 return B_NO_TRANSLATOR; 155 156 status_t err = B_OK; 157 hpgs_istream *istream = hpgs_new_wrapper_istream(source); 158 159 TranslatorBitmap header; 160 ssize_t bytesWritten; 161 uint32 dataSize; 162 163 double paper_angle = 180.0; 164 double paper_border = 0.0; 165 double paper_width = 0.0; 166 double paper_height = 0.0; 167 int verbosity = 0; 168 int depth = 32; 169 int palette = 0; 170 hpgs_bool multipage = HPGS_FALSE; 171 hpgs_bool ignore_ps = HPGS_FALSE; 172 hpgs_bool do_linewidth = HPGS_TRUE; 173 hpgs_bool do_rop3 = HPGS_TRUE; 174 hpgs_bool antialias = HPGS_FALSE; 175 int image_interpolation = 0; 176 double thin_alpha = 0.25; 177 hpgs_device *size_dev = 0; 178 hpgs_bbox bbox = { 0.0, 0.0, 0.0, 0.0 }; 179 hpgs_image *image; 180 hpgs_paint_device *pdv; 181 hpgs_device *plot_dev; 182 183 size_dev = (hpgs_device *)hpgs_new_plotsize_device(ignore_ps, do_linewidth); 184 hpgs_reader *reader = hpgs_new_reader(istream, size_dev, multipage, verbosity); 185 if (hpgs_read(reader, HPGS_FALSE)) { 186 fprintf(stderr, B_TRANSLATE("no hpgs\n")); 187 err = B_NO_TRANSLATOR; 188 goto err1; 189 } 190 191 if (hpgs_getplotsize(size_dev,1,&bbox)<0) { 192 fprintf(stderr, B_TRANSLATE("no hpgs\n")); 193 err = B_NO_TRANSLATOR; 194 goto err1; 195 } 196 197 // set the appropriate page placement. 198 if (paper_width > 0.0 && paper_height > 0.0) { 199 hpgs_reader_set_fixed_page(reader,&bbox, 200 paper_width, paper_height, paper_border, paper_angle); 201 } else { 202 paper_width = 200.0 * 72.0; 203 paper_height = 200.0 * 72.0; 204 hpgs_reader_set_dynamic_page(reader,&bbox, 205 paper_width, paper_height, paper_border, paper_angle); 206 } 207 208 image = (hpgs_image*)hpgs_new_png_image((int)bbox.urx, (int)bbox.ury, depth, palette, do_rop3); 209 image->vtable->write = &my_pim_write; 210 image = (hpgs_image *)realloc(image, sizeof(my_hpgs_png_image)); 211 ((my_hpgs_png_image *)image)->target = target; 212 213 pdv = hpgs_new_paint_device(image, NULL, &bbox, antialias); 214 hpgs_paint_device_set_image_interpolation(pdv, image_interpolation); 215 hpgs_paint_device_set_thin_alpha(pdv, thin_alpha); 216 217 plot_dev = (hpgs_device *)pdv; 218 if (hpgs_reader_imbue(reader, plot_dev)) { 219 fprintf(stderr, hpgs_i18n(B_TRANSLATE("Error: Cannot imbue plot " 220 "device to reader: %s\n")), hpgs_get_error()); 221 err = B_NO_TRANSLATOR; 222 goto err2; 223 } 224 225 dataSize = (int)bbox.urx * 4 * (int)bbox.ury; 226 227 header.magic = B_TRANSLATOR_BITMAP; 228 header.bounds.Set(0, 0, (int)bbox.urx - 1, bbox.ury - 1); 229 header.rowBytes = (int)bbox.urx * 4; 230 header.colors = B_RGBA32; 231 header.dataSize = dataSize; 232 233 // write out Be's Bitmap header 234 swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap), 235 B_SWAP_HOST_TO_BENDIAN); 236 bytesWritten = target->Write(&header, sizeof(TranslatorBitmap)); 237 if (bytesWritten < B_OK) { 238 fprintf(stderr, B_TRANSLATE("Write error %s\n"), 239 strerror(bytesWritten)); 240 err = bytesWritten; 241 goto err2; 242 } 243 244 if ((size_t)bytesWritten != sizeof(TranslatorBitmap)) { 245 fprintf(stderr, "TranslatorBitmap\n"); 246 err = B_IO_ERROR; 247 } 248 249 if (err == B_OK && hpgs_read(reader, HPGS_FALSE)) { 250 fprintf(stderr, hpgs_i18n(B_TRANSLATE("Error: Cannot process plot " 251 "data %s\n")), hpgs_get_error()); 252 err = B_NO_TRANSLATOR; 253 } 254 255err2: 256 free(pdv); 257 free(image); 258 259err1: 260 free(reader); 261 free(size_dev); 262 free(istream->stream); 263 free(istream); 264 return err; 265} 266 267 268BView * 269HPGSTranslator::NewConfigView(TranslatorSettings *settings) 270{ 271 return new ConfigView(BRect(0, 0, 225, 175)); 272} 273 274 275// #pragma mark - 276 277 278BTranslator * 279make_nth_translator(int32 n, image_id you, uint32 flags, ...) 280{ 281 if (n != 0) 282 return NULL; 283 284 return new HPGSTranslator(); 285} 286 287