{"id":18993477,"url":"https://github.com/mdibyo/imagemanipulation","last_synced_at":"2026-04-15T10:30:19.966Z","repository":{"id":14023375,"uuid":"16725302","full_name":"mDibyo/imageManipulation","owner":"mDibyo","description":"This is the first project of the Spring 2014 CS 61B (Data Structures) class at UC Berkeley. It implements an image-storing data structure and the ability to blur the image and detect its sobel edges. It then implements a sparse Run Lengthening Implementation representation and provides methods for converting between the two formats.","archived":false,"fork":false,"pushed_at":"2014-02-21T02:57:05.000Z","size":5504,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-01T15:25:14.615Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mDibyo.png","metadata":{"files":{"readme":"readme","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-11T09:07:27.000Z","updated_at":"2014-03-05T17:37:32.000Z","dependencies_parsed_at":"2022-08-26T00:14:30.740Z","dependency_job_id":null,"html_url":"https://github.com/mDibyo/imageManipulation","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mDibyo%2FimageManipulation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mDibyo%2FimageManipulation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mDibyo%2FimageManipulation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mDibyo%2FimageManipulation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mDibyo","download_url":"https://codeload.github.com/mDibyo/imageManipulation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240008083,"owners_count":19733253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T17:21:33.372Z","updated_at":"2026-04-15T10:30:19.900Z","avatar_url":"https://github.com/mDibyo.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"                               CS 61B Project 1\n            Color Images, Edge Detection, and Run-Length Encodings\n                   Due midnight Saturday, February 22, 2014\n\nWarning:  This project is time-consuming.  Start early.\n\nThis is an individual assignment; you may not share code with other students.\n\nGetting started:  You will find the code for this assignment in ~cs61b/hw/pj1/.\nStart by copying it into your own pj1 directory.\n\nIn this project you will implement two simple image processing operations on\ncolor images:  blurring and edge detection.  You will use libraries to read and\nwrite files in the TIFF image format.  One option in TIFF files is that they\ncan be compressed if there are many adjacent pixels of the same color; the\ncompressed form is called a run-length encoding.  You will write code to\nconvert an image into a run-length encoding and back.\n\nEach image is a rectangular matrix of color pixels, which are indexed as\nfollows (for a 4x3 image):\n\n                         ------\u003e x\n\n                     |   -----------------------------\n                     |   | 0, 0 | 1, 0 | 2, 0 | 3, 0 |\n                   y |   -----------------------------\n                     |   | 0, 1 | 1, 1 | 2, 1 | 3, 1 |\n                     v   -----------------------------\n                         | 0, 2 | 1, 2 | 2, 2 | 3, 2 |\n                         -----------------------------\n\nNote that the origin is in the upper left; the x-coordinate increases as you\nmove right, and the y-coordinate increases as you go down.  (This conforms to\nJava's graphics commands, though you won't need to use them directly in this\nproject.)  We use the notation (i, j) to denote the pixel whose x-coordinate is\ni and whose y-coordinate is j.\n\nEach pixel has three numbers in the range 0...255 representing the red, green,\nand blue intensities of the pixel.  These three bytes are known as the RGB\nvalues of the image.  A pixel in which all three values are zero is pure black,\nand a pixel in which all three values are 255 is bright white.  Although Java\nhas a \"byte\" integer type, its range is -128...127, so we will usually use\nJava's \"short\" type for methods that take RGB parameters or return RGB values.\n\nPart I:  Image Blurring and Edge Detection\n==========================================\nThis part is worth 40% of your total score.  (8 points out of 20).\n\nImplement a class called PixImage that stores a color image.  The PixImage\nclass will include methods for reading or changing the image's pixels.  It will\nalso include a method for blurring an image and a method for detecting edges in\nan image.  We have provided a skeleton file named PixImage.java that includes\nprototypes for the public methods the class offers.  You are required to\nprovide implementations of all these methods.\n\nA PixImage is described by its size and the RGB values of each pixel, but it is\nup to you to decide _how_ a PixImage stores a color image.  You should\ncertainly use one or more arrays; otherwise, you have some freedom to choose\nthe details.\n\nThe size of a PixImage is determined when it is constructed, and does not\nchange afterwards.  There is one PixImage constructor, which takes two integers\nas input, representing the width and height of the image, and returns an image\nof the specified size.  For example, the statement\n\n    PixImage image = new PixImage(w, h);\n\nshould create a w x h Image object.  In your implementation, you may define any\nfields, additional methods, additional classes, or other .java files you wish,\nbut you cannot change the prototypes in PixImage.java.  We will test your code\nby calling your public methods directly, so it is important that you follow\nthis rule.  Please read PixImage.java carefully for an explanation of what\nmethods you must write.  The most important of these are boxBlur(), a simple\nimage blurring algorithm, and sobelEdges(), an edge detection algorithm.\n\nThe pixels of a PixImage can be changed with the method setPixel().  However,\nthe methods boxBlur() and sobelEdges() should NEVER change \"this\" original\nPixImage; they should construct a new PixImage and update it to show the\nresults.  The pixels in the new, output PixImage should depend only on the\npixels in \"this\" original PixImage.  To obtain correct behavior, you will be\nworking with two PixImages simultaneously, reading pixels from one and writing\n(modifying) pixels in the other.\n\nIn an image, a pixel not on the boundary has nine \"neighbors\":  the pixel\nitself and the eight pixels immediately surrounding it (to the north, south,\neast, and west, and the four diagonal neighbors).  For the sake of exposition,\nwe consider each pixel to be its own \"neighbor\".  A pixel on the boundary has\nsix neighbors if it is not a corner pixel; only four neighbors if it is a\ncorner pixel.  In both boxBlur() and sobelEdges(), the contents of any\nparticular output pixel depend only on the contents of its neighbors in the\ninput image.\n\nboxBlur() simply sets each output pixel to be the average of its neighbors\n(including itself) in \"this\" input PixImage.  This means summing up the\nneighbors and dividing by the number of neighbors (4, 6, or 9).  The sum might\nnot be divisible by the number of neighbors, but the output pixel values must\nbe integers, so we will allow Java to round non-integer quotients toward zero\n(as it always does when it divides one integer by another).\n\nEach color (red, green, blue) is blurred separately.  The red input should have\nNO effect on the green or blue outputs, etc.\n\nboxBlur() takes a parameter \"numIterations\" that specifies a number of repeated\niterations of box blurring to perform.  If numIterations is zero or negative,\nboxBlur() should return \"this\" PixImage (rather than construct a new PixImage).\nIf numIterations is positive, the return value is a newly constructed PixImage\nshowing what \"this\" PixImage would become after being blurred \"numIterations\"\ntimes.  IMPORTANT:  each iteration of blurring should be writing to a\n_different_ PixImage than the one produced by the previous iteration.  You\nshould NEVER be reading and writing pixels in the same image simultaneously,\nand you will get the wrong answer if you try.\n\nsobelEdges() implements the Sobel edge detection algorithm.  The output\nPixImage will be a grayscale image (i.e. red == green == blue for every pixel)\nwith light pixels where edges appear in \"this\" input PixImage (i.e. where\nregions of contrasting colors meets) and dark pixels everywhere else.  If you\nimagine that the image is a continuous field of color, the Sobel algorithm\ncomputes an approximate gradient of the color intensities at each pixel.\n\nFor each pixel (x, y), you will compute an approximate gradient (gx, gy) for\neach of the three colors.  As with blurring, the intensity of pixel (x, y) in\nthe output PixImage depends only on the neighbors of (x, y) in \"this\" input\nPixImage, and the red, green, and blue intensities are treated separately at\nfirst.  The red gradient (gx, gy) is a 2D vector that locally approximates the\ndirection of greatest increase of the red pixel intensities (and depends ONLY\non the red intensities of the pixels.)  If two regions of very different red\nintensities meet at the pixel (x, y), then (gx, gy) is a long vector that is\nroughly perpendicular to the boundary where the constrasting regions meet.\n\f\nWe compute the red gradient (gx, gy) with the following _convolutions_.\n\n         --------------     ----------------------------------------------\n         | 1 | 0 | -1 |     | x - 1, y - 1 |   x  , y - 1 | x + 1, y - 1 |\n         --------------     ----------------------------------------------\n    gx = | 2 | 0 | -2 |  *  | x - 1,   y   |   x  ,   y   | x + 1,   y   |\n         --------------     ----------------------------------------------\n         | 1 | 0 | -1 |     | x - 1, y + 1 |   x  , y + 1 | x + 1, y + 1 |\n         --------------     ----------------------------------------------\n\n         ----------------   ----------------------------------------------\n         |  1 |  2 |  1 |   | x - 1, y - 1 |   x  , y - 1 | x + 1, y - 1 |\n         ----------------   ----------------------------------------------\n    gy = |  0 |  0 |  0 | * | x - 1,   y   |   x  ,   y   | x + 1,   y   |\n         ----------------   ----------------------------------------------\n         | -1 | -2 | -1 |   | x - 1, y + 1 |   x  , y + 1 | x + 1, y + 1 |\n         ----------------   ----------------------------------------------\n\nThe boxes on the right store the red pixel intensities for the neighbors of (x,\ny).  The convolution operation \"*\" simply means that we multiply each box on\nthe left with the corresponding box on the right, then sum the nine products.\n(It's like an inner product, aka dot product, of two vectors of length 9.\nNote that this is NOT matrix multiplication!)  The green and blue gradients are\ndefined likewise.\n\n(If you are interested in further details, see the Wikipedia page\nhttp://en.wikipedia.org/wiki/Sobel_operator .)\n\nThis gives us three gradient vectors for each pixel (red, green, and blue).\nDefine the _energy_ of a gradient vector (gx, gy) to be the square of its\nlength; by Pythagoras' Theorem, the energy is gx * gx + gy * gy.  Define the\n_energy_ of a pixel to be the sum of its red, green, and blue energies.\n(If you think of a pixel's three gradients together as being a vector in\na six-dimensional space, the pixel's energy is the square of the length of that\nsix-dimensional vector.)\n\n    energy(x, y) = gx(red)^2 + gy(red)^2 + gx(green)^2 + gy(green)^2 +\n                   gx(blue)^2 + gy(blue)^2.\n\nIMPORTANT:  You must compute the energy EXACTLY.  The pixel intensities are of\ntype \"short\", but the energy is usually too large to fit in a \"short\".  Thus\nyou must cast all the gradient vectors to type \"long\" or \"int\" BEFORE you\ncompute any squares, and you must keep the results as \"long\" or \"int\" for the\nrest of the computation.\n\nThe maximum possible value of a Sobel gradient (for one color) is (1020, 1020),\nso each pixel's energy (combining all three colors) is a number in the range\n0...6,242,400.  We have provided a method mag2gray() in the PixImage class\nthat takes a pixel energy of type \"long\" and flattens it down to a grayscale\nintensity in the range 0...255.  The map is logarithmic, so that images over a\nwide range of intensities will reveal their edges.  However, energies of\nroughly 5,080 and below map to intensity zero, so very-low contrast edges do\nnot appear in the output PixImage.  Don't worry if you don't understand\nmag2gray(); JUST DON'T CHANGE mag2gray().\n\nIn your output PixImage, set the red, green, and blue intensities of the pixel\n(x, y) to be the value mag2gray(energy(x, y)).\n\nPixels on the boundary of the output image require special treatment, because\nthey do not have nine neighbors.  We treat them by _reflecting_ the image\nacross each image boundary.  (Imagine the image is sitting right on the shore\nof a lake, so an upside-down copy of the image is reflected below it.)  Thus,\nwe treat the pixel (-1, 2) as if it had the same RGB intensities as (0, 2), and\nthe pixel (1, height) as if it had the same RGB intensities as (1, height - 1).\nThen we compute the Sobel convolutions as usual.  The reflections prevent\nspurious \"edges\" from appearing on the boundaries of the image.\n\n(Hint:  programming will be a lot easier if you write helper functions that do\nthe reflection for you, and use them for every pixel access in your edge\ndetector, so you don't have to think about it again.)\n\nWe have provided Java classes to help you see your output images and debug your\nimplementation of Part I, in these files:\n\n    Blur.java\n    Sobel.java\n\nThe main() methods in these classes read an image in TIFF format, use your code\nto perform blurring and/or edge detection, write the modified image in TIFF\nformat, and display the input and output images.  You will need to compile them\nagainst the JAI image libraries in the .jar files we have included, which\nmay require you to add the .jar files to your \"classpath\".  In Unix:\n\n    javac -cp \"jai_core.jar:jai_codec.jar\" *.java\n\nBoth programs take one or two command-line arguments.  The first argument\nspecifies the name of an input image file in TIFF format.  (If you specify no\narguments, the programs will remind you how to use them.)  The optional second\nargument specifies the number of iterations of your box blurring filter to\nperform.  For example, if you run\n\n    java -cp \".:jai_core.jar:jai_codec.jar\" Blur image.tiff 3\n\nthen Blur will load the image from image.tiff, perform three iterations of\nblurring, write the blurred image to a file named blur_image.tiff, and display\nthe input and output images.  If you omit the second command-line argument, the\ndefault number of iterations is 1.\n\nThe Sobel program does Sobel edge detection.  Optionally, it will also perform\niterations of blurring prior to edge detection.  A small amount of blurring\ntends to make edge detection more robust in images whose lines of contrast are\nnot very sharp.  If you run\n\n    java Sobel image.tiff 5\n\nthen Sobel will load the image from image.tiff, perform five iterations of\nblurring, perform Sobel edge detection on the blurred image, write the blurred\nimage to a file named blur_image.tiff, write the grayscale-edge image to a file\nnamed edge_image.tiff, and display all three images (1 input, 2 output).  If\nyou omit the second command-line argument, no blurring is performed, and no\nblurred image is written nor displayed.  (Sobel also has an optional third\ncommand-line argument that you shouldn't try until you complete Part III.)\n\nWe have included some .tiff files for you to play with.  There is also a bit of\ntest code for the boxBlur() and sobelEdges() methods in the main() method of\nPixImage.java.\n\nYou might find it useful to check out the methods in ImageUtils.java that read\nand write the TIFF files.  We have also included a copy of the TIFF standard\n(the file TIFF6.pdf) for those who are curious.  Neither of these things are\nnecessary to complete the project, but if you want more control over writing\nimages to files for your own entertainment, it is easy to modify Blur.java or\nSobel.java for that purpose.\n\f\nPart II:  Converting a Run-Length Encoding to an Image\n======================================================\nThis part is worth 25% of your total score.  (5 points out of 20).\n\nA large number of large image files can consume a lot of disk space.  Some\nPixImages can be stored more compactly if we represent them as \"run-length\nencodings.\"  Imagine taking all the rows of pixels in the image, and connecting\nthem into one long strip.  Think of the pixels as being numbered thusly:\n\n                        -----------------------------\n                        |   0  |   1  |   2  |   3  |\n                        -----------------------------\n                        |   4  |   5  |   6  |   7  |\n                        -----------------------------\n                        |   8  |   9  |  10  |  11  |\n                        -----------------------------\n\nSome images have long strips of pixels of the same color (RGB intensities).\nIn particular, the grayscale images produced by sobelEdges() can have large\nuniform regions, especially where no edges are detected.  Run-length encoding\nis a technique in which a strip of identical consecutive pixels (possibly\nspanning several rows of the image) are represented as a single record or\nobject.  For instance, the following strip of intensities:\n\n            ------------------------------------------------------\n            | 7 | 7 | 7 | 88 | 88 | 88 | 88 | 88 | 0 | 0 | 0 | 0 |\n            ------------------------------------------------------\n              0   1   2    3    4    5    6    7   8   9   10  11\n\ncould be represented with just three records, each representing one \"run\":\n\n                             --------------------\n                             | 7,3 | 88,5 | 0,4 |\n                             --------------------\n\n\"7,3\" means that there are three consecutive 7's, followed by \"88,5\" to signify\nfive consecutive 88's, and then \"0,4\" for four jet black pixels.  With this\nencoding, a huge image whose pixels are mostly one color (like daily comic\nstrips, which are mostly white) can be stored in a small amount of memory.  The\nTIFF image format has run-length encoding built in, so in these cases it can\nproduce shorter image files.  (Note that the TIFF encoder we'll be using only\ngives us a savings when there are runs of pixels for which all three colors are\nidentical.  However, it is also possible to write TIFF files in which the three\ncolors are separated, so one can exploit runs within a single color.)\n\nYour task is to implement a RunLengthEncoding class, which represents a\nrun-length encoding as a linked list of \"run\" objects.  It is up to you whether\nto use a singly- or doubly-linked list, but a doubly-linked list might make\nPart IV easier.  (You are not permitted to use large arrays for this purpose.)\n\nBecause this is a data structures course, please use your own list class(es) or\nones you have learned in class.  In future courses, it will sometimes make more\nsense for you to use a linked list class written by somebody else, such as\njava.util.LinkedList.  However, in CS 61B this is forbidden, because I want you\nto always understand every detail of how your data structures work.  Likewise,\nyou may not use java.util.Vector or other data structures libraries.\n\f\nPart II(a):  Implement two simple constructors for RunLengthEncodings.  One\nconstructs a run-length encoding of a jet black image.  The other constructs\na run-length encoding based on four arrays provided as parameters to the\nconstructor.  These arrays tell you exactly what runs your run-length encoding\nshould contain, so you are simply converting arrays to a linked list.  (Read\nthe prototype in RunLengthEncoding.java.)\n\nPart II(b):  Your run-length encodings will be useful only if other classes\nare able to read your encodings after you create them.  Therefore, implement\nthe iterator() method in the RunLengthEncoding class and the RunIterator()\nconstructor, the hasNext() method, and the next() method in the RunIterator\nclass.\n\nThese methods work together to provide an interface by which other classes can\nread the runs in your run-length encoding, one by one.  A calling application\nbegins by using RunLengthEncoding.iterator() to create a new RunIterator i that\npoints to the first run in the run-length encoding--the run that contains pixel\n(0, 0).  (Outside classes should never call the RunIterator() constructor\ndirectly; only RunLengthEncoding.iterator() should do that.)  Each time\ni.next() is invoked, it returns the next run--represented as an array of four\nints--until every run has been returned.  The returned array encodes a run by\nstoring the length of the run (the number of pixels) at index zero, the red\npixel intensity at index one, the green pixel intensity at index two, and the\nblue pixel intensity at index three.  (This four-int array is constructed in\nnext(), and can be discarded by the calling method after use.  This array\nshould not be part of your RunLengthEncoding data structure!  It must be\nfreshly constructed for the sole purpose of returning four ints.)\n\nGiven an iterator i, i.hasNext() returns true if it has more runs to return.\nIt returns false if i has already been used to return every run, letting the\ncalling program know that there are no more runs in the encoding.  Calling\nprograms should always check i.hasNext() before they call i.next(); if they\ncall i.next() at the end of the encoding, i.next() may throw an exception and\ncrash your program.  (If a calling application wants to reset i so it points\nback to the first run again, it has to construct a brand new RunIterator.)\n\nPlease read the file RunIterator.java carefully for more information.  You\nmight also find it helpful to look up the Iterator class in the Java API.\n\nPart II(c):  Implement a toPixImage() method in the RunLengthEncoding class,\nwhich converts a run-length encoding to a PixImage object.\n\nRead RunLengthEncoding.java carefully for an explanation of what methods\nyou must write.  The fields of the PixImage class MUST be private, and the\nRunLengthEncoding class cannot manipulate these fields directly.  Hence,\nthe toPixImage() method will rely upon the PixImage() constructor and the\nsetPixel() method.\n\nYou cannot change any of the prototypes in RunLengthEncoding.java or\nRunIterator.java--except the RunIterator() constructor, which you can give any\nsignature you like, as it is called only from RunLengthEncoding.iterator().\nWe will test your code by calling your public methods directly.\n\nThere is a bit of test code for Parts II, III, and IV in the main() method of\nRunLengthEncoding.java.\n\f\nPart III:  Converting an Image to a Run-Length Encoding\n=======================================================\nThis part is worth 25% of your total score.  (5 points out of 20).\n\nWrite a RunLengthEncoding constructor that takes a PixImage object as its sole\nparameter and converts it into a run-length encoding of the PixImage.\n\nThe fields of the PixImage class MUST be private, so the RunLengthEncoding\nconstructor will rely upon the getWidth(), getHeight(), getRed(), getGreen(),\nand getBlue() methods.\n\nTesting\n-------\nThe following is worth 1 point out of the 5, but should probably be done as\nsoon as you can during Part III.\n\nYour RunLengthEncoding implementation is required to have a check() method,\nwhich walks through your run-length encoding and checks its validity.\nSpecifically, it should print a warning message if any of the following\nproblems are found:\n\n    - If two consecutive runs have exactly the same type of contents.\n      For instance, a \"99,12\" run followed by an \"99,8\" run is illegal, because\n      they should have been consolidated into a single run of twenty 99's.\n    - If the sum of all the run lengths doesn't equal the size (in pixels) of\n      the PixImage; i.e. its width times its height.\n    - If a run has a length less than 1.\n\nYou may find that the check() method is very useful in helping to debug your\nRunLengthEncoding() constructors and setPixel() in Part IV.  I also recommend\nimplementing a toString() method for your RunLengthEncoding so you can print\nand examine it to help debugging.\n\nIf the Sobel program is given three (or more) command-line arguments,\nregardless of what the third argument is, it will write the grayscale-edge\nimage twice, once as an uncompressed TIFF file and once as a run-length encoded\nTIFF file.  The two TIFF files will be different and have different lengths,\nbut the images should look identical.  If they don't, there is probably a bug\nin your run-length encoding method or your RunIterator.\n\nYou might find it interesting to compare the sizes of the two TIFF files.  (Not\nsurprisingly, the disparity is greatest for the input file black.tiff, which is\nall black pixels.)\n\f\nPart IV:  Changing a Pixel in a Run-Length Encoding\n===================================================\nThe last part is the hardest, but it is only worth 10% of the total score\n(2 points out of 20), so don't panic if you can't finish it.\n\nImplement the setPixel() method of the RunLengthEncoding class, which is\nsimilar to the setPixel() method of the PixImage class.  However, this code is\nmuch trickier to write.  Observe that setPixel() can lengthen, or even shorten,\nan existing run-length encoding.  To change a pixel in a run-length encoded\nimage, you will need to find the right run in the linked list, and sometimes\nbreak it apart into two or three runs.  If the changed pixel is adjacent to\nother pixels of identical color, you should consolidate runs to keep memory use\ndown.  (Your check() method ensures that your encoding is as compact as\npossible.)\n\nIMPORTANT:  For full points, your setPixel() method must run in time\nproportional to the number of runs in the encoding.  You MAY NOT convert the\nrun-length encoding to a PixImage object, change the pixel in the PixImage, and\nthen convert back to a run-length encoding; not only is that much too slow, it\nwill be considered CHEATING and punished accordingly.\n\nTest Code\n---------\nWe are still working on an autograder for the project, and will provide it when\nit is ready.  Until then, there is some test code in the main() methods of both\nPixImage and RunLengthEncoding, and the programs Blur and Sobel can also help.\n\nThe autograder will assign some, but not all, of the points for the project.\nAdditional points will be assigned by a human reader for partly finished code\nand for your check() method, which is not autogradeable.  Points may be\nsubtracted if you break some of the rules stated above, especially the rules on\nwhere you must use arrays and where you must use linked lists.\n\nSubmitting your Solution\n------------------------\nMake sure that your program compiles and runs on the _lab_ machines with the\nautograding program before you submit it.  Change (cd) to your pj1 directory,\nwhich should contain PixImage.java, RunLengthEncoding.java, RunIterator.java,\nand any other .java files you wish to submit.  If your implementation uses\n.java files in addition to those we have specified, have no fear:  the \"submit\"\nprogram will ask you which .java files in your pj1 directory you want to\nsubmit.  From your pj1 directory, type \"submit pj1\".\n\nAfter submitting, if you realize your solution is flawed, you may fix it and\nsubmit again.  You may submit as often as you like.  Only the last version you\nsubmit will be graded, unless you inform your reader promptly that you would\nprefer to have an earlier submission graded instead.\n\nIf your submission is late, you will lose 1% of your earned score for every two\nhours (rounded up) your project is late.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdibyo%2Fimagemanipulation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdibyo%2Fimagemanipulation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdibyo%2Fimagemanipulation/lists"}