Can I use part of Processing source code in my code?


#1

I’m making a small Java tool in Eclipse, that basically converts images to a specific format, and I would like to use code from Processing in it, instead of importing the whole core.jar library.
The specific code I want to use is split() and join() functions found here:

I’m not going to sell my result, only share it to a couple of people in need of such a tool. I will put Processing in credits in the output from the -h tag.

Am I allowed to do this? How I should go about this? What would be the most proper text to write as a credit for Processing?

edit: I did read the license information at the beginning of that file. However, what would be the best way to include that GNU Lesser General Public License, and the copyright notices? Put it only in the source code, or have my code output it on -h tag, or some other tag?


#2

Java’s bundled String class got those 2 methods already: :wink:

  1. Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#split(java.lang.String)
  2. Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.CharSequence...)

#3

But if you’d rather prefer to go w/ PApplet’s split() or join() original methods w/o modifying them, and considering its limited distribution, you could simply put those 2 static methods in their own “.java” file, wrapped up inside a class w/ some made up name. :file_cabinet:

In its header, you can post the link to the original “PApplet.java” file and just state its license is LGPL 2.1. :registered:

“MiniPApplet.java”:

/**
 This file contains 2 LGPL2.1 methods [split() & join()] from this link below:
 https://GitHub.com/processing/processing/blob/master/core/src/processing/core/PApplet.java
 */

package processing.core;

import java.util.List;
import java.util.ArrayList;

public class MiniPApplet {
  static public String[] split(String value, char delim) {
    if (value == null) return null;

    char chars[] = value.toCharArray();
    int splitCount = 0; //1;
    for (int i = 0; i < chars.length; i++) {
      if (chars[i] == delim) splitCount++;
    }

    if (splitCount == 0) {
      String splits[] = new String[1];
      splits[0] = value;
      return splits;
    }

    String splits[] = new String[splitCount + 1];
    int splitIndex = 0;
    int startIndex = 0;
    for (int i = 0; i < chars.length; i++) {
      if (chars[i] == delim) {
        splits[splitIndex++] =
          new String(chars, startIndex, i-startIndex);
        startIndex = i + 1;
      }
    }

    splits[splitIndex] =
      new String(chars, startIndex, chars.length-startIndex);

    return splits;
  }

  static public String[] split(String value, String delim) {
    List<String> items = new ArrayList<>();
    int index;
    int offset = 0;
    while ((index = value.indexOf(delim, offset)) != -1) {
      items.add(value.substring(offset, index));
      offset = index + delim.length();
    }
    items.add(value.substring(offset));
    String[] outgoing = new String[items.size()];
    items.toArray(outgoing);
    return outgoing;
  }

  static public String join(String[] list, char separator) {
    return join(list, String.valueOf(separator));
  }

  static public String join(String[] list, String separator) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < list.length; i++) {
      if (i != 0) sb.append(separator);
      sb.append(list[i]);
    }
    return sb.toString();
  }
}

You can now import those methods into your tool class like this: :toolbox:
import static processing.core.MiniPApplet.*;


#4

Oh. I guess I will use these instead.
But, I have 2 questions now:
What do I do if I will suddenly have a need for some other function in Processing, or someone else’s project under same/similar license, with same conditions? What should I do then?

And, why Processing code reinvents those functions if they are in Java already? Is it faster that way? And if so, then, well, I want those faster functions, and the problem is still there! :v


#5

Didn’t see your second reply.
But, still, wouldn’t that be, uhh, function theft? That thing about the license, and including it with parts of this code, and all that stuff makes me pretty anxious about not following them - even if no one notices if I don’t and it’s harmless!
To be specific, I’m talking about this:

/* ...
  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA
*/

#6

Well, String.join() method is from Java 8:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.CharSequence...)

Dunno exactly, but Processing should be at least as old as Java 4? :older_man:

Indeed String::split() method is from Java 4: :flushed:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#split(java.lang.String)

But PApplet.split() is overloaded to also accept a char besides a String as its delimiter parameter for convenience: :stuck_out_tongue:
Processing.org/reference/split_.html


#7

GPL belongs to a small group of open source licenses denominated copyleft: :arrow_left:

As long as we point to the original file, distribute it under the same license, and acknowledge its author(s), it’s no theft at all. :copyright:


#8

Ah, that, I guess, answers the licensing question for me.

And, now that I thought about it, String.split() method uses a REGEX for splitting the input string, meanwhile PApplet.split() uses just a normal string.
I guess it would make sense to keep their split() for backwards compatibility, and that replacing their code with something that converts that normal string to a REGEX compliant filter(I guess by adding a backslash before every character) would be slower.

Thanks!


#9

If we just pass a vanilla String argument like ", ", it’ll behave the same way for both methods. :innocent:


#10

But, I guess, it would be different for more complex arguments. That link to String.split() that you provided in your first reply mentions that it uses REGEX, so I guess I will have to keep that in mind.


#11

Are you gonna use more complex regex arguments in your tool class? :question:
If so, you can’t use Processing’s own PApplet.split() method anymore. :heavy_division_sign:
Java’s String::split() method works regardless the passed String is vanilla or regex. :coffee:


#12

I will not use any regex expression other than what’s possible by PApplet.split(), as I pretty much want to split a path to the file by /, then split last element of that split by .(to get the file’s extension), then replace that last split to “bmp”, and then connect it all back.
However, by reading up on regex on Java’s site I found out that “.” is a regex expression that means any character. I replaced it with “\\.”, with “\\” as an escape sequence for a “\”, and that “\” being an escape sequence for “.” so it wouldn’t match “any character”.

P.S. When writing this comment, for “\\” I had to write “\\\\” to make an escape sequence for this comment to write an escape sequence for Java’s string constant that contains an escape sequence to the regex filter! :smiley:


#13

You don’t need split() for parsing paths! Just use methods from Java’s File class: :open_file_folder:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/io/File.html

Along w/ some methods from class String: :abc:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html

final File f = sketchFile("img.bmp");
println(f);

final String folderpath = f.getParent();
println(folderpath);

final String file = f.getName();
println(file);

final int idx = file.indexOf('.');
final String filename = file.substring(0, idx);
println(filename);

final String ext = file.substring(idx);
println(ext);

exit();

#14

Or, ideally, Path - https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html


#15

Well, I guess I should use the getName() method for the name, but indexOf returns the position of the first occurence, and not the last one that I need.
What if the user feeds in a picture called thing.stuff.thing.image.whatever.jpg? Then it will be renamed to thing.bmp, which would be less acceptable.

Hmm, maybe I could just reverse the filename, then do indexOf, then replace the extension with “pmb.”, and then reverse it back and add to the end of getParent?

In the end, I don’t think it really matters, as the performance impact of using split and join once per run would be as negligible as the performance impact of reversing the string, indexOf, and reversing it back - and the first method seems to be more readable, at least for me!

So I’ll just replace the first split to get filename with getName, and keep the second split.

Thanks for the extended info though!


#16

lastIndexOf() -> Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#lastIndexOf(int)


#17

Oh my goodness, you just keep on saving the day! xD

Thanks yet again! I’ll use that instead! :smiley: