#usage "Import a bitmap\n" "

" "Import a bitmap into an EAGLE drawing." "

" "Author: support@cadsoft.de" // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED // Builtin variables are used to provide information at runtime. // int argc (number of arguments given to the RUN command) // string argv[] arguments given to the RUN command // (argv[0] is the full ULP file name) string ulp_path = ""; // see argv[] *** string bmpcolor[]; string bmps[]; string run_info = " "; string Version = "1.0.1"; string fileName; int nBytes = 0; // count bytes of file (fileName) int ColorBits = 0; // used bits for color int AdrStart, AdrEnd = 0; // Start & End of BITMAP-Data int length = 0; // length of bmp-Data int Byte4Group = 0; // bmp-Data organized as 4-byte groups int Layer = 200; // 1st used layer real xScale = 1; // scale x real yScale = 0; // scale y int X = 0; // count pixels x int Y = 0; // count pixels y string xy = ""; int colorscan = 0; // flag for color scanning int cselmax = 32; // max 32 colors selectable int Result = 0; real Offset = .5; // fffset Wire width int mBit[]; // bit line for operating string grid[] = { "INCH", // grid units "MIL", "MM", "MIC" }; int unit = 1; // default unit = mil int scaled = 1; // flag for DPI Scale Ratio real vmin[] = { 1, 0.001, 0.001, 0.1 }; real vmax[] = { 30.0, 3000.0, 800.0, 800000.0 } ; string Grid = grid[unit]; // default grid // get parameter PDI, Scale, Aspect Ratio, mic, mm, mil INCH ... string menuedlg[] = { "Dots Per INCH", "Scale factor for a pixel", "Aspect-Ratio m" } ; string menuval0[] = { "&Value between 1 and 10000 dots", "&Value between 0.01 and 30.0 Inch", "&Value between 0.01 and 30.0 Inch" }; string menuval1[] = { "&Value between 1 and 10000 dots", "&Value between 0.001 and 3000.0 mil", "&Value between 0.001 and 3000.0 mil" }; string menuval2[] = { "&Value between 1 and 10000 dots", "&Value between 0.0001 and 800.0 mm", "&Value between 0.0001 and 800.0 mm" }; string menuval3[] = { "&Value between 1 and 10000 dots", "&Value between 0.1 and 800000.0 micron", "&Value between 0.1 and 800000.0 micron" }; string menulbl = menuedlg[1]; string menuinfo = menuval1[1]; string ratiologo ; // table of used colors in Bitmap int colorUsed[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int colorSelect[] ; char c[]; // the file as Byte-Array // set / clear all colorUsed flags void setall(int set) { for(int n = 0; n < pow(2, ColorBits); n++) { colorUsed[n] = set; } return; } void ScriptLine(int Line) { // for(int cs = 0; cs < cselmax; cs++) { // extract max 32 colors for(int cs = 0; cs < ColorBits; cs++) { // extract max 32 colors sprintf(run_info, "%d Line %d Color #%d ", Y, Line, cs); dlgRedisplay(); if(colorSelect[cs] > -1) { // -1 color not used int lineColor = colorSelect[cs]; // extraction color int line = 0; printf("change layer %d;\n", Layer + cs); for(int z = 0; z < X; z++) { if(mBit[z] == lineColor) { // if color used if(line == 0) { // start of line in script (rectangle) printf("RECT (%.5f ", (z - Offset) * xScale); printf("%.5f)", (Line - Offset) * yScale); line = 1; } } else { if(line == 1) { printf( "(%.5f ", (z - Offset) * xScale); // end of line in script (rectangle) printf( "%.5f);\n", (Line + Offset) * yScale); line = 0; } } } if(line == 1) { printf( "(%.5f ", (z - Offset) * xScale); // end of line in script(rectangle) printf( "%.5f);\n", (Line + Offset) * yScale); line = 0; } } } return; } // Generate Script from BitMaP void GenScript(void) { int xByte = 4 * Byte4Group; // organised by groups of 4 bytes int bmpBits; for(int yRead = 0; yRead < Y; yRead++) { // counter for lines / Y for(int xRead = 0; xRead < xByte; xRead ++) { bmpBits = c[AdrStart + yRead * xByte + xRead]; switch (ColorBits) { case 1 : for(int bitcnt = 7; bitcnt > -1; bitcnt--) { mBit[(xRead * 8) + (7 - bitcnt)] = bmpBits; mBit[(xRead * 8) + (7 - bitcnt)] >>= bitcnt; mBit[(xRead * 8) + (7 - bitcnt)] &= 0X1; } break; case 4 : mBit[xRead * 2 ] = bmpBits; mBit[xRead * 2 + 1] = bmpBits; mBit[xRead * 2 ] >>= 4; mBit[xRead * 2 + 1] &= 0x0f; break; case 8 : mBit[xRead] = bmpBits; break; } } if(colorscan) { for(int z = 0; z < X; z++) { colorUsed[mBit[z]]++; // set flag for used color } } else { ScriptLine(yRead); // generate Eagle Script line } } return; } // bmp file info string bmpDaten(void) { // diagnostics string st = ""; string cmd = ""; printf( "Bitmap Start \t = %d\n", AdrStart); cmd = st; printf( "Bitmap End \t = %d\n", AdrEnd); cmd += st; printf( "Bitmap length \t = %d\n", length); cmd += st; printf( "high / pixel - Y \t = %d\n", Y); cmd += st; printf( "wide / pixel - X \t = %d\n", X); cmd += st; printf( "4-Byte Group(s) \t = %d\n", Byte4Group); cmd += st; printf( "Bits / Color \t = %d (Colors %.0f)\n", ColorBits, pow(2, ColorBits)); cmd += st; printf( "File length \t = %d\n", nBytes); cmd += st; return cmd; } // Select menu for 2 color BITmap void Cselect2(void) { Result = dlgDialog("Select used colors in " + fileName) { dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgSpacing(3); for(int colum = 0 ; colum < 2; colum++) { dlgCheckBox("", colorUsed[colum]); } dlgSpacing(6); dlgStretch(1); } dlgHBoxLayout { dlgSpacing(3); dlgStretch(0); dlgLabel(""); dlgStretch(1); // stretch bottom } dlgStretch(0); dlgSpacing(20); dlgLabel(" Select up to 2 colors "); dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgPushButton("+OK") dlgAccept(); dlgStretch(0); dlgPushButton("-ESC") dlgReject(); dlgStretch(1); dlgPushButton("&Set all") setall(1); dlgStretch(0); dlgPushButton("&Clear all") setall(0); dlgStretch(0); } dlgStretch(1); }; if (Result == 0) exit (0); return; } // Select menu for 16 color BITmap void Cselect16(void) { Result = dlgDialog("Select used colors" + fileName) { dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgSpacing(3); for(int colum = 0 ; colum < 16; colum++) { dlgCheckBox("", colorUsed[colum]); } dlgSpacing(6); dlgStretch(1); } dlgHBoxLayout { dlgSpacing(3); dlgStretch(0); dlgLabel(""); dlgStretch(1); // stretch bottom } dlgStretch(0); dlgSpacing(20); dlgLabel(" Select up to 16 colors "); dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgPushButton("+OK") dlgAccept(); dlgStretch(0); dlgPushButton("-ESC") dlgReject(); dlgStretch(1); dlgPushButton("&set all") { setall(1); dlgRedisplay();} dlgStretch(0); dlgPushButton("&clear all") { setall(0); dlgRedisplay();} dlgStretch(0); } dlgStretch(1); }; if (Result == 0) exit (0); return; } // Select menu for 256 color BITmap void Cselect256(void) { // dlgMessageBox("please be patient\nif you have a slow computer!", "OK"); Result = dlgDialog("Select used colors " + fileName) { dlgVBoxLayout { dlgStretch(0); // ********* 550 DO NOT CHANGE THIS VALUE ********* dlgHBoxLayout dlgSpacing(550); // ********* 550 DO NOT CHANGE THIS VALUE ********* dlgStretch(0); for(int row = 0 ; row < 8; row++) { dlgHBoxLayout { dlgVBoxLayout { dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgSpacing(3); for(int colum = 0 ; colum < 32; colum++) { dlgCheckBox("", colorUsed[row * 32 + colum]); } dlgSpacing(6); dlgStretch(1); } dlgHBoxLayout { dlgSpacing(3); dlgStretch(0); dlgLabel(bmps[row]); dlgStretch(1); } } dlgStretch(1); // stretch right } dlgStretch(1); // stretch bottom } dlgStretch(1); } dlgStretch(0); dlgVBoxLayout { dlgStretch(0); dlgSpacing(20); string hc; sprintf( hc, " Select up to %d colors ", cselmax); dlgLabel(hc); dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgPushButton("+OK") dlgAccept(); dlgStretch(0); dlgPushButton("-ESC") dlgReject(); dlgStretch(1); dlgPushButton("&set all") setall(1); dlgStretch(0); dlgPushButton("&clear all") setall(0); dlgStretch(0); } dlgStretch(1); } dlgStretch(1); }; if (Result == 0) exit (0); return; } // select colors int selectColors(void) { switch (ColorBits) { case 1 : Cselect2(); break; case 4 : Cselect16(); break; case 8 : Cselect256(); break; } for(int n = 0; n < cselmax; n++) { colorSelect[n] = -1; // reset selected colors } int cs; for(int s = 0; s < 256; s++) { if(colorUsed[s]) { colorSelect[cs] = s; cs++; } } return cs; } // select colors by scan array void selectMenue() { int cs; do { cs = selectColors(); string hx; if (cs > cselmax) { sprintf( hx, "Do not use more than %d colors!", cselmax); dlgMessageBox(hx, "Ok"); } if (cs < 1) { sprintf( hx, "No colors selected!"); dlgMessageBox(hx, "Ok"); } } while (cs > cselmax || cs == 0); return; } // header from Script, define Layer void scriptheader(void) { printf("# generated with %s %s\n", argv[0], Version); printf("# from %s\n", fileName); printf("Grid %s %.6f ON;\n", Grid, xScale); for(int cs = 0; cs < cselmax; cs++) { // max 32 color extract if(colorSelect[cs] > -1) { if(Layer + cs > 99){ // user defined layer printf( "LAYER %d %dbmp;\n", Layer + cs, Layer + cs); printf( "SET FILL_LAYER %d 10;\n", Layer); printf( "SET COLOR_LAYER %d %d;\n", Layer + cs, cs + 1); } } } printf( "CHANGE LAYER %d;\n", Layer); printf("SET UNDO_LOG OFF;\n"); return; } // get flag for scan colors int scan(void) { if (ColorBits == 1) return 0; return (dlgDialog("Used Colors?") { dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgVBoxLayout { dlgGroup("") { string st = ""; sprintf(st, " :\nis a %.0f color bitmap\nist eine %.0f-Farben-Bitmap\n", pow(2, ColorBits), pow(2, ColorBits)); dlgLabel(fileName + st); dlgLabel(bmpcolor[ColorBits]); } dlgGroup("") { dlgStretch(1); dlgHBoxLayout { dlgStretch(0); dlgPushButton("+scan used colors") dlgAccept(); dlgStretch(1); dlgPushButton("-no scan") dlgReject(); dlgStretch(0); } dlgStretch(0); } dlgStretch(1); } dlgStretch(1); } dlgStretch(1); } ); } void colors24(void) { string st = "bmp file contains more than 256 colors, reduce colors before use.\n\n" + "Die benutzte Anzahl der Farben in der bmp-Datei ist groesser 256.\n" + "Verringern Sie zuerst die Anzahl der Farben in der bmp-Datei.\n\n"; dlgMessageBox(st, "&OK"); return; } void menuchange(void) { menulbl = menuedlg[scaled]; switch (scaled) { case 0 : ratiologo = ""; break; case 1 : ratiologo = ""; break; case 2 : ratiologo = ""; break; } switch (unit) { case 0 : menuinfo = menuval0[scaled]; break; case 1 : menuinfo = menuval1[scaled]; break; case 2 : menuinfo = menuval2[scaled]; break; case 3 : menuinfo = menuval3[scaled]; break; } return ; } //--------------------------------- void imp_bmp(void) { colorscan = 0; // reset scanning mode switch(scaled) { case 0 : Grid = grid[0]; yScale = 1 / xScale; // Dots Per Inch xScale = yScale; break; case 1 : Grid = Grid = grid[unit]; yScale = xScale; break; case 2 : Grid = Grid = grid[unit]; yScale = xScale / X; // Aspect Ratio = Width / Pixel X xScale = yScale; break; } menuinfo = "Dot scale"; scriptheader(); GenScript(); // generate script string printf("SET UNDO_LOG ON;\n"); printf("WINDOW FIT;\n"); printf( "Change Size %.3f;\n", yScale * 2); printf("CHANGE FONT VECTOR;\n"); printf( "TEXT '" + fileName + "' (0 %.3f);\n", -5 * yScale ); return; } void runscript(void) { string script; int s = fileread(script, ulp_path + "bmp.scr"); Result = dlgDialog("Accept Script?") { dlgHBoxLayout dlgSpacing(300); dlgHBoxLayout { dlgVBoxLayout dlgSpacing(300); dlgTextEdit(script); } dlgHBoxLayout { dlgStretch(0); dlgPushButton("+Run script") dlgAccept(); dlgStretch(1); dlgPushButton("-Cancel") dlgReject(); dlgStretch(0); } }; if (Result == 1) exit ("script '" + ulp_path + "bmp.scr'"); else exit (0); } void showbmp() { if ( X < 1200 && Y < 750) { dlgMessageBox("File: " + fileName + "
", "OK"); } else dlgMessageBox("The BMP-File ist to big to print complete on screen!", "OK"); return; } // ***************** main **************** void main(void) { ulp_path = filedir(argv[0]); ratiologo = ""; bmpcolor[1] = ""; bmpcolor[4] = ""; bmpcolor[8] = ""; bmps[0] = ""; bmps[1] = ""; bmps[2] = ""; bmps[3] = "", bmps[4] = ""; bmps[5] = ""; bmps[6] = ""; bmps[7] = ""; fileName = dlgFileOpen("Select a bmp file", "", "*.bmp"); if (fileName == "") exit (0); run_info = "File = " + filename(fileName); nBytes = fileread(c, fileName); // read file in array // up to 31 bytes - not all used if(c[0] != 'B') { dlgMessageBox(fileName + ":\nis not a bmp file.\n\nist keine bmp-Datei.", "OK"); exit(0); } if(c[1] != 'M') { dlgMessageBox(fileName + ":\nis not a bmp file.\n\nist keine bmp-Datei.", "OK"); exit(0); } if(c[21] > 0) { dlgMessageBox(fileName + ":\nToo many pixels in x direction\n" + "\nAnzahl der Pixel in X zu gross\n", "OK"); exit (0); } if(c[25] > 0) { dlgMessageBox(fileName + ":\nToo many pixels y direction\n" + "\nAnzahl der Pixel in Y zu gross\n", "OK"); exit (0); } // case 6 TO 9, 14 TO 17 not used ColorBits = c[28]; // counter of ColorBits if(ColorBits > 8) { colors24(); // to many colors, break exit(0); } AdrEnd = c[2] + c[3] * 256 + c[4] * 256 * 256 + c[5] * 256 * 256 * 256; AdrStart = c[10]+ c[11] * 256 + c[12] * 256 * 256 + c[13] * 256 * 256 * 256; X = c[18] + c[19] * 256 + c[20] * 65536 + c[21] * 256 * 256 * 256; Y = c[22] + c[23] * 256 + c[24] * 65536 + c[25] * 256 * 256 * 256; sprintf(xy, " X = %5d Pixel\n Y = %5d Pixel", X, Y); length = AdrEnd - AdrStart; // bitmap legth Byte4Group = length / Y / 4; if(scan()) { // first scan used colors colorscan = 1; GenScript(); } selectMenue(); //--------------------------------- int d = 1; while(d) { dlgDialog("Info "+ fileName) { dlgHBoxLayout { dlgVBoxLayout { dlgStretch(0); dlgGroup("File data") { dlgLabel(xy, 1); } dlgStretch(0); dlgLabel(ratiologo, 1); dlgStretch(1); } dlgStretch(0); dlgVBoxLayout { dlgStretch(0); dlgGroup("Format") { dlgRadioButton("&DPI", scaled) { unit = 0; menuchange(); } dlgRadioButton("&Scaled", scaled) {menuchange(); } dlgRadioButton("&Aspect/Ratio m ", scaled) { menuchange(); } } dlgStretch(0); dlgGroup("Unit") { dlgRadioButton("&Inch", unit) { menuchange(); dlgRedisplay();} dlgRadioButton("Mi&l", unit) { if ( scaled == 0) scaled = 1; menuchange(); } dlgRadioButton("&MM", unit) { if ( scaled == 0) scaled = 1; menuchange(); } dlgRadioButton("Mi&cron", unit) { if ( scaled == 0) scaled = 1; menuchange(); } } dlgStretch(0); dlgPushButton("S&elected colors") selectMenue(); dlgStretch(1); } } dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgVBoxLayout { dlgLabel(menulbl, 1); dlgLabel(menuinfo, 1); dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgRealEdit(xScale, vmin[unit], vmax[unit]); dlgStretch(0); dlgSpacing(100); dlgStretch(0); } dlgStretch(0); dlgSpacing(10); dlgStretch(0); dlgLabel("Choose start layer for &1st selected color"); dlgStretch(0); dlgHBoxLayout { dlgStretch(0); dlgSpinBox(Layer, 1, 255); dlgStretch(0); dlgSpacing(100); dlgStretch(0); } dlgStretch(0); } dlgStretch(1); } dlgStretch(1); dlgLabel(run_info, 1); dlgHBoxLayout { dlgStretch(0); dlgPushButton("+OK") { dlgAccept(); output(ulp_path + "bmp.scr", "wtD") { d = 0; imp_bmp(); } runscript(); } dlgStretch(1); dlgPushButton("-Cancel") exit(0); dlgPushButton("show &Bitmap") showbmp(); } }; } }