diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/DkWxImgszFrame.wxc |
Initial commit
Diffstat (limited to 'support/dktools/DkWxImgszFrame.wxc')
-rw-r--r-- | support/dktools/DkWxImgszFrame.wxc | 960 |
1 files changed, 960 insertions, 0 deletions
diff --git a/support/dktools/DkWxImgszFrame.wxc b/support/dktools/DkWxImgszFrame.wxc new file mode 100644 index 0000000000..40be8be76c --- /dev/null +++ b/support/dktools/DkWxImgszFrame.wxc @@ -0,0 +1,960 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2012-xxxx +license = bsd + + +%% wx-gui + +type = frame +icon = dkicon_bitmap +menu bar = mbMain +contents = mainSizer + +[wxMenuBar mbMain] +contents = mFile +contents = mExtras +contents = mHelp + +[wxMenu mFile] +contents = miOpen +contents = miExit +text = sTexts[1] + +[wxMenuItem miOpen] +text = sTexts[49] +id = DkWxImgsz_Open +tip = sTexts[50] + +[wxMenuItem miExit] +text = sTexts[2] +id = DkWxImgsz_Quit +tip = sTexts[19] + +[wxMenu mExtras] +text = sTexts[38] +contents = miOptions + +[wxMenuItem miOptions] +text = sTexts[39] +tip = sTexts[40] +id = DkWxImgsz_Options + +[wxMenu mHelp] +text = sTexts[27] +contents = miHelpContents +contents = miHelpAbout + +[wxMenuItem miHelpContents] +text = sTexts[28] +tip = sTexts[30] +id = DkWxImgsz_Help + +[wxMenuItem miHelpAbout] +text = sTexts[29] +tip = sTexts[31] +id = DkWxImgsz_About + +[wxBoxSizer mainSizer] +direction = vertical +contents = $space(10) +contents = horizontalSizer +contents = $space(10) +contents = statusSizer +contents = $space(10) + +[wxBoxSizer horizontalSizer] +grow = yes +proportion = 1 +contents = $space(10) +contents = inputDataSizer left top +contents = $space(10) +contents = bCalculate centered-x centered-y +contents = $space(10) +contents = outputDataSizer left top +contents = $space(10) + +[wxGridBagSizer inputDataSizer] +grid = 5 5 +contents = lOriginalImage 0 0 1 2 left centered-y +contents = lWidth +1 0 1 1 right centered-y +contents = tWidth . +1 1 1 left centered-y +contents = lHeight +1 0 1 1 right centered-y +contents = tHeight . +1 1 1 left centered-y +contents = $space(10) +1 0 1 1 left +contents = lChangeType +1 0 1 2 left centered-y +contents = lAction +1 0 1 1 right centered-y +contents = cbAction . +1 1 1 left centered-y +contents = lMinimum +1 0 1 1 right centered-y +contents = tMinimum . +1 1 1 left centered-y +contents = lMaximum +1 0 1 1 right centered-y +contents = tMaximum . +1 1 1 left centered-y + +[wxStaticText lOriginalImage] +text = sTexts[6] + +[wxStaticText lWidth] +text = sTexts[8] + +[wxTextCtrl tWidth] +tip = sTexts[20] +text = sTexts[26] + +[wxStaticText lHeight] +text = sTexts[9] + +[wxTextCtrl tHeight] +tip = sTexts[21] +text = sTexts[26] + +[wxStaticText lChangeType] +text = sTexts[10] + +[wxStaticText lAction] +text = sTexts[11] + +[wxChoice cbAction] +choices = 3 saAction +tip = sTexts[22] +# grow = yes +id = DkWxImgsz_Choice + +[wxStaticText lMinimum] +text = sTexts[15] + +[wxTextCtrl tMinimum] +tip = sTexts[23] +text = sTexts[26] + +[wxStaticText lMaximum] +text = sTexts[16] + +[wxTextCtrl tMaximum] +tip = sTexts[24] +text = sTexts[26] + +[wxBitmapButton bCalculate] +# text = sTexts[17] +bitmap = run2_bitmap +tip = sTexts[25] +id = DkWxImgsz_Run + +[wxGridBagSizer outputDataSizer] +grid = 5 5 +grow = yes +proportion = 1 +contents = lResults 0 0 1 2 left centered-y +contents = dataGrid +1 0 2 2 left top +growable row = 2 +growable column = 1 + +[wxStaticText lResults] +text = sTexts[7] + +[wxGrid dataGrid] +text style = readonly +column head = sTexts[3] +column head = sTexts[4] +column head = sTexts[5] +column head = sTexts[18] +rows = 16 +minimum size = 300 200 +grow = true +proportion = 1 + +[wxBoxSizer statusSizer] +contents = $space(10) +contents = lStatus +contents = $space(10) + +[wxStaticText lStatus] +text = sTexts[18] + + +%% header start + + +%% class start + + +/** Main window class for the wximgsz program. +*/ +class DkWxImgszFrame : public DkWxFrame +{ + private: + + /** Event table. + */ + DECLARE_EVENT_TABLE() + + protected: + + /** Localized message texts. + */ + wxChar const * const *sTexts; + + /** Red (used as background color). + */ + wxColour cRed; + + /** Red 127. + */ + wxColour cNotSoDarkRed; + + /** Green (used as background color). + */ + wxColour cGreen; + + /** Black (used as text color). + */ + wxColour cBlack; + + /** Dark red (used as text color). + */ + wxColour cDarkRed; + + /** Yellow (used as background color). + */ + wxColour cYellow; + + /** File dialog x position. + */ + int fdx; + + /** File dialog y position. + */ + int fdy; + + /** Options dialog x position. + */ + int odx; + + /** Options dialog y position. + */ + int ody; + + /** Flag: Use background colors to indicate scale factor quality. + */ + bool bUseColour; + + /** Current directory. + */ + wxString sCurrentDir; + +%% class end + public: + /** Constructor. + */ + DkWxImgszFrame( + wxChar const *applicationName, + wxChar const * const *localizedMessages, + DkWxAppHelper *applicationHelper, + DkWxHelpController *helpController, + int wxid, + int argc, + wxChar **argv + ); + + /** Destructor. + */ + ~DkWxImgszFrame(); + + /** Check whether we can close the window. + @param isLast Flag: Last top level window. + */ + bool + canClose(bool isLast); + + /** Event handler to open a file. + @param event Event to process. + */ + void + OnOpen(wxCommandEvent& WXUNUSED(event)); + + /** Event handler to quit application. + @param event Event to process. + */ + void + OnQuit(wxCommandEvent& WXUNUSED(event)); + + /** Event handler to show help contents. + @param event Event to process. + */ + void + OnHelp(wxCommandEvent& WXUNUSED(event)); + + /** Event handler to show version number. + @param event Event to process. + */ + void + OnAbout(wxCommandEvent& WXUNUSED(event)); + + /** Event handler: Run calculation. + @param event Event to process. + */ + void + OnRun(wxCommandEvent& WXUNUSED(event)); + + /** Event handler: Choice made. + @param event Event to process. + */ + void + OnChoice(wxCommandEvent & event); + + /** Event handler to set options. + @param event Event to process. + */ + void + OnOptions(wxCommandEvent& WXUNUSED(event)); + + protected: + + /** Save data entered into text fields. + */ + void saveData(); + + /** Restore data entered in text fields. + */ + void restoreData(); + + /** Enable/disable the lower text fields depending + on the current choice selection. + */ + void + enableDisableMinimumMaximum(); + + /** Calculate largest common divisor. + @param aa One number. + @param bb Other number. + @return Largest common divisor of aa and bb. + */ + long gcd(long aa, long bb); + + /** Retrieve positive long number from text field. + @param tf Text field to process. + @param bShowErrors Flag: Show message boxes for errors. + @return Positive number on success, 0L on error. + */ + long getTextCtrlContents(wxTextCtrl *tf, bool bShowErrors); + + /** Run calculation. + */ + void + run(bool bShowErrors); + + /** Run for a set of numbers. + @param w Width (or height, if inverted). + @param h Height (or width, if inverted). + @param min Minimum value. + @param max maximum value. + @param inverted Flag: w contains the hight, h the width. + */ + void + runForNumbers(long w, long h, long min, long max, int inverted); + + /** Classify factor. + @param n New value. + @param o Old value. + @return 2 for powers of 2, 1 for integer factors, 0 otherwise. + */ + int classifyFactor(long n, long o); + + /** Count bit number in a long value. + @param v Value to check. + @return Number of bits set. + */ + int countBits(long v); +}; + +%% header end + + +%% module start + +#include "wximgsz.h" +#include "dkicon.xpm" +#include "dk4verswx.h" +#include "run2.xpm" + +$!trace-include + + + +/** Event table for the DkWxImgszFrame class. +*/ +BEGIN_EVENT_TABLE(DkWxImgszFrame, wxFrame) + EVT_MENU(DkWxImgsz_Quit, DkWxImgszFrame::OnQuit) + EVT_MENU(DkWxImgsz_Help, DkWxImgszFrame::OnHelp) + EVT_MENU(DkWxImgsz_About, DkWxImgszFrame::OnAbout) + EVT_MENU(DkWxImgsz_Options, DkWxImgszFrame::OnOptions) + EVT_MENU(DkWxImgsz_Open, DkWxImgszFrame::OnOpen) + EVT_BUTTON(DkWxImgsz_Run, DkWxImgszFrame::OnRun) + EVT_CHOICE(DkWxImgsz_Choice, DkWxImgszFrame::OnChoice) +END_EVENT_TABLE() + + + +%% constructor start + +DkWxImgszFrame::DkWxImgszFrame( + wxChar const *applicationName, + wxChar const * const *localizedMessages, + DkWxAppHelper *applicationHelper, + DkWxHelpController *helpController, + int wxid, + int argc, + wxChar **argv +) : DkWxFrame(applicationName, applicationHelper, helpController, wxid), + cRed(255, 91, 91), + cNotSoDarkRed(127, 0, 0), + cGreen(127, 255, 127), + cBlack(0, 0, 0), + cDarkRed(63, 0, 0), + cYellow(255, 255, 0), + sCurrentDir(wxT("")) +{ + /* + Icon for main window. + */ +#if defined(__WXMSW__) + wxIcon dkicon_bitmap(wxT("aaaaa")); +#else + wxIcon dkicon_bitmap(xpm_dkicon); +#endif + wxIcon run2_bitmap(xpm_run2); + fdx = -1; fdy = -1; + odx = -1; ody = -1; + sTexts = localizedMessages; + wxString saAction[] = { + wxString(localizedMessages[12]), + wxString(localizedMessages[13]), + wxString(localizedMessages[14]) + }; + bUseColour = true; +%% constructor end + if (lOriginalImage) { + lOriginalImage->SetForegroundColour(cNotSoDarkRed); + } + if (lChangeType) { + lChangeType->SetForegroundColour(cNotSoDarkRed); + } + if (lResults) { + lResults->SetForegroundColour(cNotSoDarkRed); + } + SetTitle(localizedMessages[0]); +#if 0 + restorePosition(); +#endif + restoreData(); + enableDisableMinimumMaximum(); +} + +%% module end + +void +DkWxImgszFrame::OnHelp(wxCommandEvent& WXUNUSED(event)) +{ + openHelp(); +} + + +static wxChar const wximgsz_version[] = { + wxT("wximgsz (part of dktools-") +}; + +static wxChar const wximgsz_versnumber[] = { + DKT_VERSION_WX +}; + +static wxChar const wximgsz_versend[] = { + wxT(")") +}; +void +DkWxImgszFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +{ + wxString sVersion(wximgsz_version); + sVersion.Append(wximgsz_versnumber); + sVersion.Append(wximgsz_versend); + sVersion.Append(sTexts[53]); + sVersion.Append(wxT("Copyright (c) 2013-2016 Dirk Krause")); + sVersion.Append(sTexts[53]); + sVersion.Append(sTexts[53]); + sVersion.Append(sTexts[54]); + sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.")); + sVersion.Append(sTexts[53]); + sVersion.Append(sTexts[53]); + sVersion.Append(sTexts[55]); + sVersion.Append(wxT("http://dktools.sourceforge.net\n")); + sVersion.Append(wxT("http://www.wxwidgets.org\n")); + sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n")); + sVersion.Append(wxT("http://www.ijg.org\n")); + sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n")); + sVersion.Append(wxT("http://www.zlib.org")); + wxMessageBox(sVersion, sTexts[35]); +} + + +void +DkWxImgszFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) +{ + $? "+ DkWxImgszFrame::OnQuit" + Show(false); + Close(); + $? "- DkWxBmepsFrame::OnQuit" +} + + + +void +DkWxImgszFrame::OnOpen(wxCommandEvent& WXUNUSED(event)) +{ + wxString s(wxT("")); + $? "+ DkWxImgszFrame::OnOpen" + s.Append(wxT("BMP files (*.bmp)|*.bmp")); + s.Append(wxT("|PNG files (*.png)|*.png")); + s.Append(wxT("|JPEG files (*.jpg)|*.jpg|JPEG files (*.jpeg)|*.jpeg")); + s.Append(wxT("|TIFF files (*.tif)|*.tif|TIFF files (*.tiff)|*.tiff")); + s.Append(wxT("|XPM files (*.xpm)|*.xpm")); + s.Append(wxT("|All files (*.*)|*.*")); +#if wxCHECK_VERSION(2, 9, 0) + wxFileDialog dlg(this, sTexts[48], sCurrentDir, wxT(""), s, wxFD_OPEN); +#else + wxFileDialog dlg(this, sTexts[48], sCurrentDir, wxT(""), s, wxOPEN); +#endif + pHelper->setRelatedPosition(this, &dlg, &fdx, &fdy); + if(wxID_OK == dlg.ShowModal()) { + wxString path = dlg.GetPath(); + wxImage img; + if(img.LoadFile(path)) { + int w = img.GetWidth(); + int h = img.GetHeight(); + if((w > 0) && (h > 0)) { + wxString sWidth; + wxString sHeight; + sWidth.Printf(wxT("%d"), w); + sHeight.Printf(wxT("%d"), h); + if((tWidth) && (tHeight)) { + tWidth->SetValue(sWidth); + tHeight->SetValue(sHeight); + Refresh(); + Update(); + run(false); + } + } else { + /* ERROR: Illegal image dimensions! */ + wxMessageBox(sTexts[51], sTexts[52], (wxOK | wxICON_ERROR), this); + } + } else { + /* ERROR: Failed to load file! */ + wxMessageBox(sTexts[51], sTexts[52], (wxOK | wxICON_ERROR), this); + } + } + dlg.GetPosition(&fdx, &fdy); + $? "- DkWxBmepsFrame::OnOpen" +} + + + +void +DkWxImgszFrame::OnOptions(wxCommandEvent& WXUNUSED(event)) +{ + $? "+ DkWxImgszFrame::OnOptions" + DkWxImgszOptionsDialog dlg(this, sTexts[41], sTexts); + pHelper->setRelatedPosition(this, &dlg, &odx, &ody); + dlg.SetValue(bUseColour); + if(dlg.ShowModal() == wxID_OK) { + bUseColour = dlg.GetValue(); + } + dlg.GetPosition(&odx, &ody); + $? "- DkWxBmepsFrame::OnOptions" +} + + +void +DkWxImgszFrame::run(bool bShowErrors) +{ + long w = 0L; + long h = 0L; + long min = 0L; + long max = 0L; + int action = 0; + $? "+ DkWxImgszFrame::run" + w = getTextCtrlContents(tWidth, bShowErrors); + if(w > 0L) { + h = getTextCtrlContents(tHeight, bShowErrors); + if(h > 0L) { + switch((action = cbAction->GetCurrentSelection())) { + case 2: { + min = getTextCtrlContents(tMinimum, bShowErrors); + if(min > 0L) { + max = getTextCtrlContents(tMaximum, bShowErrors); + } + } break; + case 1: { + min = getTextCtrlContents(tMinimum, bShowErrors); + if(min > 0L) { + max = getTextCtrlContents(tMaximum, bShowErrors); + } + } break; + default: { + min = 1L; max = w; action = 1; + } break; + } + if((w > 0L) && (h > 0L) && (min > 0L) && (max > 0L)) { + switch(action) { + case 2: { + runForNumbers(h, w, min, max, 1); + } break; + default: { + runForNumbers(w, h, min, max, 0); + } break; + } + } + } + } + $? "- DkWxImgszFrame::run" +} + + + +void +DkWxImgszFrame::OnRun(wxCommandEvent& WXUNUSED(event)) +{ + $? "+ DkWxImgszFrame::OnRun" + run(true); + $? "- DkWxImgszFrame::OnRun" +} + + + +DkWxImgszFrame::~DkWxImgszFrame() +{ +} + + + +bool +DkWxImgszFrame::canClose(bool isLast) +{ + $? "+ DkWxBmepsFrame::canClose %d", (isLast ? 1 : 0) + if(isLast) { + saveData(); + } $? "- DkWxBmepsFrame::canClose 1" + return true; +} + + + +static wxChar const * const wximgsz_keys[] = { +$!string-table macro=wxT +wximgsz.width +wximgsz.height +wximgsz.selection +wximgsz.minimum +wximgsz.maximum +wximgsz.colours +$!end +}; + +void +DkWxImgszFrame::saveData() +{ + long i[] = { + 0L, // Width + 0L, // Height + 0L, // Selection + 0L, // Minimum + 0L, // Maximum + 0L // bUseColour + }; + long l; + if((tWidth->GetValue()).ToLong(&l)) { + i[0] = l; + } + if((tHeight->GetValue()).ToLong(&l)) { + i[1] = l; + } + i[2] = (long)(cbAction->GetCurrentSelection()); + if(i[2] < 0L) i[2] = 0L; + if((tMinimum->GetValue()).ToLong(&l)) { + i[3] = l; + } + if((tMaximum->GetValue()).ToLong(&l)) { + i[4] = l; + } + i[5] = ((bUseColour) ? 1L : 0L); + if(pHelper) { + pHelper->saveMultipleLongs(wximgsz_keys, i); + } +} + + +void +DkWxImgszFrame::restoreData() +{ + wxString sWidth; + wxString sHeight; + wxString sMinimum; + wxString sMaximum; + long i[] = { + 1024L, // Width + 768L, // Height + 0L, // Selection + 200L, // Minimum + 800L, // Maximum + 1L // bUseColour + }; + if(pHelper) { + pHelper->retrieveMultipleLongs(wximgsz_keys, i); + sWidth.Printf(wxT("%ld"), i[0]); + sHeight.Printf(wxT("%ld"), i[1]); + sMinimum.Printf(wxT("%ld"), i[3]); + sMaximum.Printf(wxT("%ld"), i[4]); + tWidth->SetValue(sWidth); + tHeight->SetValue(sHeight); + tMinimum->SetValue(sMinimum); + tMaximum->SetValue(sMaximum); + cbAction->SetSelection((int)(i[2])); + bUseColour = ((i[5]) ? true : false); + } +} + + + +void +DkWxImgszFrame::enableDisableMinimumMaximum() +{ + if(0 == cbAction->GetCurrentSelection()) { + tMinimum->SetEditable(false); + tMaximum->SetEditable(false); + tMinimum->Enable(false); + tMaximum->Enable(false); + } else { + tMinimum->SetEditable(true); + tMaximum->SetEditable(true); + tMinimum->Enable(true); + tMaximum->Enable(true); + } +} + + + +void +DkWxImgszFrame::OnChoice(wxCommandEvent & event) +{ + enableDisableMinimumMaximum(); +} + + + +long +DkWxImgszFrame::gcd(long aa, long bb) +{ + long back = 0L; + long h = 0L; + long a; + long b; + + a = aa; + b = bb; + while(b > 0L) { + h = a % b; + a = b; + b = h; + } + back = a; + return back; +} + + +long +DkWxImgszFrame::getTextCtrlContents(wxTextCtrl *tf, bool bShowErrors) +{ + long back = 0L; + long l = 0L; + if((tf->GetValue()).ToLong(&l)) { + back = l; + } + if(0 >= back) { + if(bShowErrors) { + tf->SetFocus(); + wxMessageBox(sTexts[33], sTexts[32], (wxOK | wxICON_ERROR), this); + } + } + return back; +} + + + +void +DkWxImgszFrame::runForNumbers(long w, long h, long min, long max, int inverted) +{ + long gd; + long w0; + long h0; + long nw; + long nh; + long i; + long z; + long n; + long g2; + int lineno; + int cl; + int rows; + int found = 0; + + gd = gcd(w, h); + if(gd > 0L) { + /* + Minimum rectangle. + */ + w0 = w / gd; + h0 = h / gd; + /* + Remove all grid lines. + */ + rows = dataGrid->GetNumberRows(); + dataGrid->DeleteRows(0, rows); + /* + Build and fill new grid. + */ + lineno = 0; + i = 1; + lStatus->SetForegroundColour(cBlack); + lStatus->SetLabel(sTexts[18]); + while((i * w0) <= max) { + if((i * w0) >= min) { + found = 1; + nw = i * w0; + nh = i * h0; + /* Classify factor. */ + cl = classifyFactor(nw, w); + g2 = gcd(nw, w); + z = nw / g2; n = w / g2; + dataGrid->AppendRows(1); + dataGrid->SetCellTextColour(lineno, 0, cBlack); + dataGrid->SetCellTextColour(lineno, 1, cBlack); + dataGrid->SetCellTextColour(lineno, 2, cBlack); + switch(cl) { + case 2: { + if(bUseColour) { + dataGrid->SetCellBackgroundColour(lineno, 2, cGreen); + } else { + dataGrid->SetCellValue(lineno, 3, sTexts[36]); + } + } break; + case 1: { + if(bUseColour) { + dataGrid->SetCellBackgroundColour(lineno, 2, cYellow); + } else { + dataGrid->SetCellValue(lineno, 3, sTexts[37]); + } + } break; + default: { + if(bUseColour) { + dataGrid->SetCellBackgroundColour(lineno, 2, cRed); + } else { + dataGrid->SetCellValue(lineno, 3, wxT("")); + } + } break; + } + if(bUseColour) { + dataGrid->SetCellValue(lineno, 3, wxT("")); + } + { + wxString sRowHead; + wxString sFactor; + wxString sWidth; + wxString sHeight; + + sRowHead.Printf(wxT("%d"), (lineno + 1)); + if(n > 1L) { + sFactor.Printf(wxT("%ld / %ld"), z, n); + } else { + sFactor.Printf(wxT("%ld"), z); + } + if(inverted) { + sWidth.Printf(wxT("%ld"), nh); + sHeight.Printf(wxT("%ld"), nw); + } else { + sWidth.Printf(wxT("%ld"), nw); + sHeight.Printf(wxT("%ld"), nh); + } + dataGrid->SetRowLabelValue(lineno, sRowHead); + dataGrid->SetCellValue(lineno, 0, sWidth); + dataGrid->SetCellValue(lineno, 1, sHeight); + dataGrid->SetCellValue(lineno, 2, sFactor); + dataGrid->SetCellAlignment(lineno, 0, wxALIGN_CENTRE, wxALIGN_CENTRE); + dataGrid->SetCellAlignment(lineno, 1, wxALIGN_CENTRE, wxALIGN_CENTRE); + dataGrid->SetCellAlignment(lineno, 2, wxALIGN_CENTRE, wxALIGN_CENTRE); + dataGrid->SetCellAlignment(lineno, 3, wxALIGN_CENTRE, wxALIGN_CENTRE); + } + lineno++; + } + i++; + } + dataGrid->AutoSizeColumns(); + dataGrid->EnableDragColSize(true); + if(0 == found) { + lStatus->SetLabel(sTexts[34]); + lStatus->SetForegroundColour(cDarkRed); + } + Refresh(); + Update(); + } +} + + + +int +DkWxImgszFrame::classifyFactor(long n, long o) +{ + long max; + long min; + int back = 0; + if(n > o) { + max = n; min = o; + } else { + max = o; min = n; + } + if(max % min) { + back = 0; + } else { + back = 1; + max = max / min; + if(countBits(max) == 1) { + back = 2; + } + } + return back; +} + + +int +DkWxImgszFrame::countBits(long v) +{ +#if DK3_SIZEOF_LONG > 2 +#if DK3_SIZEOF_LONG > 4 + long bitmask = 0x4000000000000000L; + int attempts = 63; +#else + long bitmask = 0x40000000L; + int attempts = 31; +#endif +#else + long bitmask = 0x4000L; + int attempts = 15; +#endif + int back = 0; + + while(attempts--) { + if(v & bitmask) { + back++; + } + bitmask = bitmask >> 1; + } + return back; +} + + |